环境: flutter sdk v1.5.4-hotfix.1@stable
对应 flutter engine: 52c7a1e849a170be4b2b2fe34142ca2c0a6fea1fjava
站在平台端的视角对通道有一个通观概览的认知以后就须要深刻内里对通讯机制须要一个深刻剖析了,以前已经了解到FlutterJNI.dispatchPlatformMessage
是平台层(java)发送数据调用的最后一层,那么继续这个调用序列:android
FluttereJNI.dispatchPlatformMessage nativeDispatchPlatformMessage(FlutterJNI.java) DispatchPlatformMessage(platform_view_android_jni.cc:56) AndroidShellHolder::GetPlatformView(platform_view_android_jni.cc:421) PlatformViewAndroid::DispatchPlatformMessage(platform_view_android.cc:92) TaskRunners::GetPlatformTaskRunner => PlatformView::task_runners_ new PlatformMessageResponseAndroid() new flutter::PlatformMessage(name, message, response) PlatformView::DispatchPlatformMessage PlatformView::Delegate::OnPlatformViewDispatchPlatformMessage() => Shell::On..() ::GetUITaskRunner TaskRunner::PostTask ...Engine::DispatchPlatformMessage
发送消息最终调用到了C++层的PlatformViewAndroid::DispatchPlatformMessage
方法, 又调用了PlatformViewAndroid
成员delegate_
的OnPlatformViewDispatchPlatformMessage
方法, 因此咱们要肯定PlatformView::Delegate
抽象类的实现体, 也就是要追踪成员被建立或赋值的地方。c++
由构造函数可知成员PlatformView::delegate_
是建立时外部传入,而PlatformViewAndroid
做为子类把它的delegate传入,因此须要了解
PlatformViewAndroid
被建立时传入的delegate对象,git
android_shell_holder.cc:63
可知建立PlatformViewAndroid
时传入的的delegate对象实际为Shell
,在其方法中又异步调用了成员engine_
的方法,即Engine::DispatchPlatformMessage
方法github
因此咱们须要shell
PlatformViewAndroid
被建立的流程Engine
被赋值或建立的时机PlatformViewAndroid
流程:AndroidShellHolder::AndroidShellHolder() ThreadHost::ThreadHost platform_thread= fml::MessageLoop::EnsureInitializedForCurrentThread platform_runner=fml::MessageLoop::GetCurrent().GetTaskRunner() Shell::Create() DartVMRef::Create(settings) Shell::Create() TaskRunner::RunNowOrPostTask lamda() => Shell::CreateShellOnPlatformThread() Shell::CreateCallback<PlatformView>(Shell&) => on_create_platform_view new PlatformViewAndroid(Shell,...)
最重要的是Shell::Create
这个方法,在调用时传入了一个回调,这个回调调用了Shell::CreateShellOnPlatformThread()
, 继续回调了on_create_platform_view
,它的实现体在AndroidShellHolder
构造函数上下文中。异步
第二个问题恰好承接了对每个问题的分析: 咱们是在建立Shell
的时候建立了PlatformViewAndroid
对象
shell.cc:38
可知engine_
也是外部传入函数
Shell::CreateShellOnPlatformThread() new Shell() on_create_platform_view => AndroidShellHolder.on_create_platform_view std::make_unique<PlatformViewAndroid>() TaskRunner::RunNowOrPostTask ...lamda => engine = std::make_unique<Engine>() (shell.cc:131) Shell::Setup engine_ = std::move(engine); (shell.cc:388)
在Shell::CreateShellOnPlatformThread
中先建立了Shell
实例, 接着建立了PlatformView
实例,接着又异步执行了一个lamda,建立了Engine
实例oop
这样前面两个重要对象的建立时机问题就终于明确了。this
继续咱们第一阶段的调用分析, 异步执行了Engine::DispatchPlatformMessage
Engine::DispatchPlatformMessage RuntimeController::DispatchPlatformMessage Window::DispatchPlatformMessage tonic::DartInvokeField(...,"_dispatchPlatformMessage")
最终由此进行到了Dart层调用
由于在AndroidShellHolder
的构造函数中Flutter建立了Shell
对象,因此一样须要明确:
AndroidShellHolder
流程:FlutterActivity.onCreate (FlutterActivity.java:89) FlutterActivityDelegate.onCreate() (FlutterActivityDelegate.java:160) FlutterView.FlutterView() (FlutterView.java:139) new FlutterNativeView(Context) (FlutterNativeView.java:47) FlutterNativeView.attach(this, false) (FlutterNativeView.java:165) FlutterJNI.attachToNative (FlutterJNI.java:423) AttachJNI(platform_view_android_jni.cc:149) java_object(env, flutterJNI) std::make_unique<AndroidShellHolder>(java_object) AndroidShellHolder::IsValid reinterpret_cast<jlong>
比较容易发现建立的时机正是FlutterJNI
绑定到FlutterNativeView
, 而FlutterJNI
的成员nativePlatformViewId
表明的正是C++AndroidShellHolder
对象,在这个过程当中重要对象如Shell
和Engine
相继被建立。
因此每次发送数据(或者平台调用dart方法)都是FlutterJNI
对象将成员nativePlatformViewId
传入c++层,转成AndroidShellHolder
对象经过Engine
最终调用到dart层