flutter 图解_深入理解Flutter消息机制

一、概述

在深入理解Flutter引擎启动 已经介绍了引擎启动阶段会创建AndroidShellHolder对象,在该过程会执行ThreadHost初始化,MessageLoop便是在这个阶段启动的。

1.1 消息流程图

MessageLoop启动流程图

afcbc9ddbc28c9e9ad56bc559285725e.png

该过程主要工作:创建线程,并给每个线程中创建相应的MessageLoop,对于Android平台创建的是MessageLoopAndroid,同时还会创建TaskRunner,之后便进入到相应MessageLoop的run()方法。

ScheduleMicrotask流程图

53ff0d3918fc4467f67d9f6b67843e68.png

1.2 MessageLoop类图

MessageLoop类图

b18b7936e0c23187f5d5067b405b2d42.png

图解:

  • Thread和MessageLoop类都有成员变量记录着TaskRunner类;
  • MessageLoopImpl类在Android系统的实现子类为MessageLoopAndroid;

二、MessageLoop启动

引擎启动过程会创建UI/GPU/IO这3个线程,代码如下。

thread_host_ = {thread_label, ThreadHost::Type::UI
                              | ThreadHost::Type::GPU
                              | ThreadHost::Type::IO};

2.1 ThreadHost初始化

[-> flutter/shell/common/http://thread_host.cc]

ThreadHost::ThreadHost(std::string name_prefix, uint64_t mask) {
  if (mask & ThreadHost::Type::Platform) {
    platform_thread = std::make_unique<fml::Thread>(name_prefix + ".platform");
  }

  if (mask & ThreadHost::Type::UI) {
    //创建线程 [见小节2.2]
    ui_thread = std::make_unique<fml::Thread>(name_prefix + ".ui");
  }

  if (mask & ThreadHost::Type::GPU) {
    gpu_thread = std::make_unique<fml::Thread>(name_prefix + ".gpu");
  }

  if (mask & ThreadHost::Type::IO) {
    io_thread = std::make_unique<fml::Thread>(name_prefix + ".io");
  }
}

根据传递的参数,可知首次创建AndroidShellHolder实例的过程,会创建3个线程名为1.ui, 1.gpu, http://1.io。

2.2 Thread初始化

[-> flutter/fml/http://thread.cc]

Thread::Thread(const std::string& name) : joined_(false) {
  fml::AutoResetWaitableEvent latch;
  fml::RefPtr<fml::TaskRunner> runner;
  thread_ = std::make_unique<std::thread>([&latch, &runner, name]() -> void {
    SetCurrentThreadName(name); //设置线程名
    fml::MessageLoop::EnsureInitializedForCurrentThread(); //[见小节2.3]
    //从ThreadLocal中获取MessageLoop指针
    auto& loop = MessageLoop::GetCurrent();
    runner = loop.GetTaskRunner();
    latch.Signal();
    loop.Run(); //运行 [见小节2.8]
  });
  latch.Wait();
  task_runner_ = runner;
}

Thread线程对象会有两个重要的成员变量:

  • thread_: 类型为unique_ptr
  • task_runner_: 类型为RefPtr

2.3 EnsureInitializedForCurrentThread

[-> flutter/fml/http://message_loop.cc]

FML_THREAD_LOCAL ThreadLocal tls_message_loop([](intptr_t value) {
  delete reinterpret_cast<MessageLoop*>(value);
});

void MessageLoop::EnsureInitializedForCurrentThread() {
  if (tls_message_loop.Get() != 0) {
    return;  //保证只初始化一次
  }
  //创建MessageLoop,并保持在tls_message_loop [见小节2.4]
  tls_message_loop.Set(reinterpret_cast<intptr_t>(new MessageLoop()));
}

创建MessageLoop对象保存在ThreadLocal类型的tls_message_loop变量中。

2.4 MessageLoop初始化

[-> flutter/fml/http://message_loop.cc]

MessageLoop::MessageLoop()
       //[见小节2.5]
    : loop_(MessageLoopImpl::Create()),
      //[见小节2.7]
      task_runner_(fml::MakeRefCounted<fml::TaskRunner>(loop_)) {
}

创建MessageLoopAndroid对象和TaskRunner对象,并保持在当前的MessageLoop对象的成员变量。

2.5 MessageLoopImpl::Create

[-> flutter/fml/http://message_loop_impl.cc]

fml::RefPtr<MessageLoopImpl> MessageLoopImpl::Create() {
#if OS_MACOSX
  return fml::MakeRefCounted<MessageLoopDarwin>();
#elif OS_ANDROID
  return fml::MakeRefCounted<MessageLoopAndroid>(); //[见小节2.6]
#elif OS_LINUX
  return fml::MakeRefCounted<MessageLoopLinux>();
#elif OS_WIN
  return fml::MakeRefCounted<MessageLoopWin>();
#else
  return nullptr;
#endif
}

针对Android平台,则MessageLoopImpl的实例为MessageLoopAndroid对象。

2.6 MessageLoopAndroid初始化

[-> flutter/fml/platform/android/http://message_loop_android.cc]

MessageLoopAndroid::MessageLoopAndroid()
    : looper_(AcquireLooperForThread()), //[见小节2.6.1]
      timer_fd_(::timerfd_create(kClockType, TFD_NONBLOCK | TFD_CLOEXEC)),
      running_(false) {
  static const i
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值