1 | sdk: [v1.5.4-hotfix.1](https://github.com/flutter/flutter/commit/7a4c33425ddd78c54aba07d86f3f9a4a0051769b)@stable |
站在平台端的视角对通道有一个通观概览的认知之后就需要深入内里对通信机制需要一个深入剖析了,之前已经了解到FlutterJNI.dispatchPlatformMessage是平台层(java)发送数据调用的最后一层,那么继续这个调用序列:
1 | FluttereJNI.dispatchPlatformMessage |
发送消息最终调用到了C++层的PlatformViewAndroid::DispatchPlatformMessage方法, 又调用了PlatformViewAndroid成员delegate_的OnPlatformViewDispatchPlatformMessage方法, 所以我们要确定PlatformView::Delegate抽象类的实现体, 也就是要追踪成员被创建或赋值的地方。
由构造函数可知成员PlatformView::delegate_是创建时外部传入,而PlatformViewAndroid作为子类把它的delegate传入,所以需要了解
PlatformViewAndroid被创建时传入的delegate对象,
android_shell_holder.cc:63可知创建PlatformViewAndroid时传入的的delegate对象实际为Shell,在其方法中又异步调用了成员engine_的方法,即Engine::DispatchPlatformMessage方法
所以我们需要
- 明确
PlatformViewAndroid被创建的流程 - 明确
Engine被赋值或创建的时机
创建PlatformViewAndroid流程:
1 | AndroidShellHolder::AndroidShellHolder() |
最重要的是Shell::Create这个方法,在调用时传入了一个回调,这个回调调用了Shell::CreateShellOnPlatformThread(), 继续回调了on_create_platform_view,其实现体上下文在AndroidShellHolder构造函数中。
创建Shell::engine_[Engine]流程:
第二个问题刚好承接了对每一个问题的分析: 我们是在创建Shell的时候创建了PlatformViewAndroid对象
shell.cc:38可知engine_也是外部传入
1 | Shell::CreateShellOnPlatformThread() |
在Shell::CreateShellOnPlatformThread中先创建了Shell实例, 接着创建了PlatformView实例,接着又异步执行了一个lamda,创建了Engine实例
这样前面两个重要对象的创建时机问题就终于明确了。
继续我们第一阶段的调用分析, 异步执行了Engine::DispatchPlatformMessage
1 | Engine::DispatchPlatformMessage |
最终由此进行到了Dart层调用
因为在AndroidShellHolder的构造函数中Flutter创建了Shell对象,所以同样需要明确:
创建AndroidShellHolder流程:
1 | FlutterActivity.onCreate (FlutterActivity.java:89) |
比较容易发现创建的时机正是FlutterJNI绑定到FlutterNativeView, 而FlutterJNI的成员nativePlatformViewId代表的正是C++AndroidShellHolder对象,在这个过程中重要对象如Shell和Engine相继被创建。
所以每次发送数据(或者平台调用dart方法)都是FlutterJNI对象将成员nativePlatformViewId传入c++层,转成AndroidShellHolder对象通过Engine最终调用到dart层