Flutter启动流程-Java层 程序入口 FlutterActivity#onCreate
创建代理类,并传入this。Host接口提供子类Hook,代理类中会在特定时机回调接口通知宿主,例如配置FlutterEngine
delegate.onAttach
:创建FlutterEngine
delegate.onCreateView
:创建FlutterView
,设置为ContentView
getFlutterShellArgs()
:从Intent中获取Flutter参数
通过代理的方式,使FlutterActivity
和FlutterFragment
共用代理类逻辑,避免重复编码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class FlutterActivity extends Activity implements FlutterActivityAndFragmentDelegate .Host , LifecycleOwner { @Override protected void onCreate (@Nullable Bundle savedInstanceState) { delegate = new FlutterActivityAndFragmentDelegate(this ); delegate.onAttach(this ); delegate.onRestoreInstanceState(savedInstanceState); setContentView(createFlutterView()); } @NonNull private View createFlutterView () { return delegate.onCreateView(...); } public FlutterShellArgs getFlutterShellArgs () { return FlutterShellArgs.fromIntent(getIntent()); } }
FlutterActivityAndFragmentDelegate
setupFlutterEngine
:创建FlutterEngine
配置PlatformPlugin(平台插件):用于接收Flutter消息,调用系统方法,例如播放声音,状态栏、导航栏、剪贴板等
配置引擎:例如注册FlutterPlugin(Flutter插件)
**创建FlutterSurfaceView
或者FlutterTextureView
**:默认使用SurfaceView,无法像普通View一样使用动画和z-index
实例化FlutterView :addView添加FlutterSurfaceView
,并添加首帧渲染监听(最终会注册到FlutterJNI中,由Native层回调通知)
flutterView.attachToFlutterEngine
:FlutterView绑定引擎
如果配置了闪屏页,还会启动闪屏页,在Flutter引擎初始化、到首帧渲染完成之间显示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class FlutterActivityAndFragmentDelegate { FlutterActivityAndFragmentDelegate(@NonNull Host host) { this .host = host; } void onAttach (@NonNull Context context) { setupFlutterEngine(); platformPlugin = host.providePlatformPlugin(host.getActivity(), flutterEngine); host.configureFlutterEngine(flutterEngine); } @NonNull View onCreateView (LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { FlutterSurfaceView flutterSurfaceView = new FlutterSurfaceView(host.getContext(), host.getTransparencyMode() == TransparencyMode.transparent); host.onFlutterSurfaceViewCreated(flutterSurfaceView); flutterView = new FlutterView(host.getContext(), flutterSurfaceView); flutterView.addOnFirstFrameRenderedListener(flutterUiDisplayListener); flutterView.attachToFlutterEngine(flutterEngine); SplashScreen splashScreen = host.provideSplashScreen(); if (splashScreen != null ) { FlutterSplashView flutterSplashView = new FlutterSplashView(host.getContext()); flutterSplashView.setId(ViewUtils.generateViewId(FLUTTER_SPLASH_VIEW_FALLBACK_ID)); flutterSplashView.displayFlutterViewWithSplash(flutterView, splashScreen); return flutterSplashView; } return flutterView; } ... return flutterSplashView; }
小结 这里包含两个关键步骤:由于流程比较长,拆开来介绍
创建FlutterEngine
:
加载Flutter资源
解析Intent参数
绑定FlutterJNI
实例
FlutterView
绑定Flutter引擎
创建FlutterView
和FlutterSurfaceView
创建FlutterRenderer
将Surface和FlutterRenderer
关联,并传给Flutter引擎
创建触摸、按键等监听器,将Android View事件发给Flutter引擎
创建FlutterEngine setupFlutterEngine 首先看下setupFlutterEngine()
方法如何获取FlutterEngine:
从FlutterEngineCache
缓存中获取预热的引擎,重写getCachedEngineId()
子类自行创建引擎,重写provideFlutterEngine
方法
创建默认引擎
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class FlutterActivityAndFragmentDelegate { void setupFlutterEngine () { String cachedEngineId = host.getCachedEngineId(); if (cachedEngineId != null ) { flutterEngine = FlutterEngineCache.getInstance().get(cachedEngineId); isFlutterEngineFromHost = true ; return ; } flutterEngine = host.provideFlutterEngine(host.getContext()); if (flutterEngine != null ) { isFlutterEngineFromHost = true ; return ; } flutterEngine = new FlutterEngine(host.getContext(), host.getFlutterShellArgs().toArray(), false , host.shouldRestoreAndSaveState()); isFlutterEngineFromHost = false ; } }
继续看FlutterEngine实例化:
FlutterJNI
:沟通Android和Flutter引擎Native代码
FlutterLoader
:加载Flutter资源、Kernel或者AOT Library路径。通过FlutterJNI初始化Native引擎
DartExecutor
:用于配置、启动、执行Dart代码。原生通过JNI和Dart通信 。
Java层调用FlutterJNI.dispatchPlatformMessage
将消息发到Native层
Native层调用FlutterJNI.handlePlatformMessage
通知Java层
XXXChannel
:创建不同的消息通道,监听和处理固定的事件,需要通过DartMessenger
来传递消息
PlatformChannel
:内部使用MethodChannel
,通知Dart层SystemUI变化,接收Dart层消息修改SystemUI、设置剪贴板等
LifecycleChannel
:内部使用BasicMessageChannel
,生命周期变化时通知Dart层
…
Channel只是封装了不同类型的消息,以及响应和处理特定消息。最终都是通过DartExecutor
调用JNI方法将消息发给Native层。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class FlutterEngine { public FlutterEngine (...) { FlutterInjector injector = FlutterInjector.instance(); if (flutterJNI == null ) { flutterJNI = injector.getFlutterJNIFactory().provideFlutterJNI(); } this .flutterJNI = flutterJNI; this .dartExecutor = new DartExecutor(flutterJNI, assetManager); this .dartExecutor.onAttachedToJNI(); xxxChannel = new XXXChannel(dartExecutor, flutterJNI); if (flutterLoader == null ) { flutterLoader = injector.flutterLoader(); } if (!flutterJNI.isAttached()) { flutterLoader.startInitialization(context.getApplicationContext()); flutterLoader.ensureInitializationComplete(context, dartVmArgs); } if (!flutterJNI.isAttached()) { attachToJni(); } this .renderer = new FlutterRenderer(flutterJNI); } }
Spawn方法用于创建多个Flutter引擎,通过FlutterEngineGroup
类进行管理,spawn引擎都由第一个引擎生成,避免重复绑定JNI对象
加载Flutter资源,解析Intent参数
ApplicationInfoLoader.load
从meta-data
配置中读取Flutter资源名称,不配置的话默认值如下
1 2 3 4 5 6 7 public final class FlutterApplicationInfo { private static final String DEFAULT_AOT_SHARED_LIBRARY_NAME = "libapp.so" ; private static final String DEFAULT_VM_SNAPSHOT_DATA = "vm_snapshot_data" ; private static final String DEFAULT_ISOLATE_SNAPSHOT_DATA = "isolate_snapshot_data" ; private static final String DEFAULT_FLUTTER_ASSETS_DIR = "flutter_assets" ; ... }
异步从Apk中提取Flutter资源,加载Flutter引擎so库
ensureInitializationComplete
:获取Activity中的Intent参数,通过FlutterJNI
传给Flutter引擎:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 public class FlutterLoader { public void startInitialization (@NonNull Context applicationContext, @NonNull Settings settings) { if (this .settings != null ) { return ; } this .settings = settings; ... if (Looper.myLooper() != Looper.getMainLooper()) { throw new IllegalStateException("startInitialization must be called on the main thread" ); } flutterApplicationInfo = ApplicationInfoLoader.load(appContext); Callable<InitResult> initTask = new Callable<InitResult>() { @Override public InitResult call () { ResourceExtractor resourceExtractor = initResources(appContext); flutterJNI.loadLibrary(); ... if (resourceExtractor != null ) { resourceExtractor.waitForCompletion(); } return new InitResult( PathUtils.getFilesDir(appContext), PathUtils.getCacheDirectory(appContext), PathUtils.getDataDirectory(appContext)); } }; initResultFuture = Executors.newSingleThreadExecutor().submit(initTask); } public void ensureInitializationComplete ( @NonNull Context applicationContext, @Nullable String[] args) { if (initialized) { return ; } ... try { InitResult result = initResultFuture.get(); List<String> shellArgs = new ArrayList<>(); ... flutterJNI.init( applicationContext, shellArgs.toArray(new String[0 ]), kernelPath, result.appStoragePath, result.engineCachesPath, initTimeMillis); initialized = true ; } catch (Exception e) { Log.e(TAG, "Flutter initialization failed." , e); throw new RuntimeException(e); } } }
FlutterJNI实例和引擎绑定 FlutterEngine.attachToJni();
中调用FlutterJNI.attachToNative
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class FlutterJNI { @UiThread public void attachToNative (boolean isBackgroundView) { ensureRunningOnMainThread(); ensureNotAttachedToNative(); nativeShellHolderId = performNativeAttach(this , isBackgroundView); } @VisibleForTesting public long performNativeAttach (@NonNull FlutterJNI flutterJNI, boolean isBackgroundView) { return nativeAttach(flutterJNI, isBackgroundView); } private native long nativeAttach (@NonNull FlutterJNI flutterJNI, boolean isBackgroundView) ; }
小结 创建和绑定Flutter引擎
DartExecutor
:注册平台通信通道,直接和FlutterJNI
通信
XXXChannel
:注册监听和响应特定的Dart消息,通过DartExecutor
分发消息,不直接和FlutterJNI
交互
FlutterLoader
:
startInitialization()
:异步从APK中提取资源
ensureInitializationComplete()
:调用FlutterJNI.nativeInit()
方法法,解析和保存Intent参数
FlutterJNI.nativeAttach()
:创建和绑定Flutter引擎
这里涉及到两个JNI方法nativeInit和nativeAttach
,后面会分析到
FlutterView关联引擎 查看FlutterView.attachToFlutterEngine
源码
FlutterRenderer
:Flutter渲染在Java层的代言人,封装渲染相关的操作,通过FlutterJNI
和Native交互
FlutterSurfaceView
:创建Android Surface,通过FlutterRenderer
传给Native操作
通过KeyBoardManager
和AndroidTouchProcessor
等将Android事件传递给引擎
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class FlutterView extends FrameLayout implements MouseCursorPlugin .MouseCursorViewDelegate { public void attachToFlutterEngine (@NonNull FlutterEngine flutterEngine) { this .flutterEngine = flutterEngine; FlutterRenderer flutterRenderer = this .flutterEngine.getRenderer(); renderSurface.attachToRenderer(flutterRenderer); keyboardManager = new KeyboardManager(this , textInputPlugin, new KeyChannelResponder[] { new KeyChannelResponder(flutterEngine.getKeyEventChannel()) }); androidTouchProcessor = new AndroidTouchProcessor(this .flutterEngine.getRenderer(), false ); sendUserSettingsToFlutter(); localizationPlugin.sendLocalesToFlutter(getResources().getConfiguration()); sendViewportMetricsToFlutter(); flutterEngine.getPlatformViewsController().attachToView(this ); } private void sendViewportMetricsToFlutter () { ... flutterEngine.getRenderer().setViewportMetrics(viewportMetrics); } }
attachToRenderer
:调用nativeSurfaceCreated()
将Surface
传到Native层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class FlutterRenderer implements TextureRegistry { public void attachToRenderer (@NonNull FlutterRenderer flutterRenderer) { ... if (isSurfaceAvailableForRendering) { connectSurfaceToRenderer(); } } private void connectSurfaceToRenderer () { flutterRenderer.startRenderingToSurface(getHolder().getSurface()); } public void startRenderingToSurface (@NonNull Surface surface) { if (this .surface != null ) { stopRenderingToSurface(); } this .surface = surface; flutterJNI.onSurfaceCreated(surface); } }
Flutter代码执行入口 上面几步完成了Flutter引擎、FlutterView、FlutterJNI等创建和绑定。但是还没执行开发者写的Flutter代码。
FlutterActivity#onStart 还是从FlutterActivity
开始分析
1 2 3 4 5 6 7 8 9 10 11 12 public class FlutterActivity extends Activity implements FlutterActivityAndFragmentDelegate .Host , LifecycleOwner { @Override protected void onStart () { super .onStart(); lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START); if (stillAttachedForEvent("onStart" )) { delegate.onStart(); } } }
FlutterActivityAndFragmentDelegate
检查Dart代码是否已经执行
从Intent中获取Flutter初始页面路由
找到Dart程序入口,执行Dart代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class FlutterActivityAndFragmentDelegate implements ExclusiveAppComponent <Activity > { void onStart () { Log.v(TAG, "onStart()" ); ensureAlive(); doInitialFlutterViewRun(); } private void doInitialFlutterViewRun () { if (host.getCachedEngineId() != null ) { return ; } if (flutterEngine.getDartExecutor().isExecutingDart()) { return ; } String initialRoute = host.getInitialRoute(); if (initialRoute == null ) { initialRoute = maybeGetInitialRouteFromIntent(host.getActivity().getIntent()); if (initialRoute == null ) { initialRoute = DEFAULT_INITIAL_ROUTE; } } ... flutterEngine.getNavigationChannel().setInitialRoute(initialRoute); String appBundlePathOverride = host.getAppBundlePath(); if (appBundlePathOverride == null || appBundlePathOverride.isEmpty()) { appBundlePathOverride = FlutterInjector.instance().flutterLoader().findAppBundlePath(); } DartExecutor.DartEntrypoint entrypoint = new DartExecutor.DartEntrypoint(appBundlePathOverride, host.getDartEntrypointFunctionName()); flutterEngine.getDartExecutor().executeDartEntrypoint(entrypoint); } }
最终会调用FlutterJNI
的nativeRunBundleAndSnapshotFromLibrary
小结
FlutterJNI动态注册Native方法 Flutter引擎和Flutter代码最终会被打包成Native动态库libengine.so
、libapp.so
。
而JNI是Java和Native通信的桥梁,因此这里先介绍下Flutter注册的方法,后面分析源码时可以直接找到对应的Native方法。
Flutter在Java层提供了唯一的入口FlutterJNI
,在Native层对应多个类,核心接口是PlatformViewAndroid
FlutterMain
:主要负责解析Java层参数
PlatformViewAndroid
:实现PlatformView
平台通用接口 ,负责Surface创建,事件分发,PlatformMessage通知等
VsyncWaiterAndroid
:实现VsyncWaiter
平台通用接口 ,监听Vsync信号,通知引擎进行绘制。
AndroidImageGenerator
:备用的图片解码方法,引擎根据需要调用Android方法进行解码,解码完成之后通知Native层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 JNIEXPORT jint JNI_OnLoad (JavaVM* vm, void * reserved) { fml::jni::InitJavaVM (vm); JNIEnv* env = fml::jni::AttachCurrentThread (); bool result = false ; result = flutter::FlutterMain::Register (env); FML_CHECK (result); result = flutter::PlatformViewAndroid::Register (env); FML_CHECK (result); result = flutter::VsyncWaiterAndroid::Register (env); FML_CHECK (result); result = flutter::AndroidImageGenerator::Register (env); FML_CHECK (result); return JNI_VERSION_1_4; }
以FlutterMain
为例,JNI方法FlutterJNI.nativeInit
对应FlutterMain.Init
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 bool FlutterMain::Register (JNIEnv* env) { static const JNINativeMethod methods[] = { { .name = "nativeInit" , .signature = "(Landroid/content/Context;[Ljava/lang/String;Ljava/" "lang/String;Ljava/lang/String;Ljava/lang/String;J)V" , .fnPtr = reinterpret_cast <void *>(&Init), }, { .name = "nativePrefetchDefaultFontManager" , .signature = "()V" , .fnPtr = reinterpret_cast <void *>(&PrefetchDefaultFontManager), }, }; jclass clazz = env->FindClass ("io/flutter/embedding/engine/FlutterJNI" ); if (clazz == nullptr ) { return false ; } return env->RegisterNatives (clazz, methods, fml::size (methods)) == 0 ; }
Flutter启动流程-Native层 上文分析过Java层的调用流程,涉及几个JNI方法,下面分析下Native层做了哪些事情
nativeInit
:对应flutter_main.cc
的Init()
方法,解析Intent参数,保存到Settings结构体中
nativeAttach
:对应platform_view_android_jni_impl.cc
的AttachJNI()
方法
创建AndroidShellHolder
创建4个TaskRunner
并指定线程,保存到TaskRunners
中
在指定线程创建Shell、DartVM、Engine、PlatformView、Rasterizer、ShellIOManager等实例
nativeSurfaceCreated
:FlutterView
将Surface传给引擎
nativeRunBundleAndSnapshotFromLibrary
:执行Flutter代码
主要分析nativeAttach方法,其他方法分析流程类似
nativeInit
调用shell/common/switches.cc
的SettingsFromCommandLine
解析参数,保存到Settings
结构体中。
注意这里switches
和settings
都属于common包,所有平台通用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include "flutter/shell/platform/android/flutter_main.h" namespace flutter {FlutterMain::FlutterMain (flutter::Settings settings) : settings_ (std::move (settings)), observatory_uri_callback_ () {} ... const flutter::Settings& FlutterMain::GetSettings () const { return settings_; } void FlutterMain::Init (JNIEnv* env, jclass clazz, jobject context, jobjectArray jargs, jstring kernelPath, jstring appStoragePath, jstring engineCachesPath, jlong initTimeMillis) { std::vector<std::string> args; args.push_back ("flutter" ); for (auto & arg : fml::jni::StringArrayToVector (env, jargs)) { args.push_back (std::move (arg)); } auto command_line = fml::CommandLineFromIterators (args.begin (), args.end ()); auto settings = SettingsFromCommandLine (command_line); ... g_flutter_main.reset (new FlutterMain (std::move (settings))); } }
nativeAttach AttachJNI 实例化AndroidShellHolder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 static jlong AttachJNI (JNIEnv* env, jclass clazz, jobject flutterJNI, jboolean is_background_view) { fml::jni::JavaObjectWeakGlobalRef java_object (env, flutterJNI) ; std::shared_ptr<PlatformViewAndroidJNI> jni_facade = std::make_shared<PlatformViewAndroidJNIImpl>(java_object); auto shell_holder = std::make_unique<AndroidShellHolder>( FlutterMain::Get ().GetSettings (), jni_facade, is_background_view); if (shell_holder->IsValid ()) { return reinterpret_cast <jlong>(shell_holder.release ()); } else { return 0 ; } }
AndroidShellHolder AndroidShellHolder
是FlutterEngine
在C++端的顶级类,将Shell
和PlatformViewAndroid
等组合在一起。每个FlutterEngine对应一个AndroidShellHolder
和一个PlatformViewAndroid
。
创建4个TaskRunner
,通过ThreadHost
指定线程,设置优先级,放到TaskRunners
中统一管理
通过Shell::Create
创建Shell对象,创建成功后回调将shell设置为PlatformViewAndroid
的委托
GetPlatformView
函数返回PlatformViewAndroid
对象,JNI几乎所有的调用都是通过AndroidShellHolder
转发给PlatformViewAndroid
处理
Launch函数用于启动引擎执行Dart代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 AndroidShellHolder::AndroidShellHolder ( flutter::Settings settings, std::shared_ptr<PlatformViewAndroidJNI> jni_facade, bool is_background_view) : settings_ (std::move (settings)), jni_facade_ (jni_facade) { static size_t thread_host_count = 1 ; auto thread_label = std::to_string (thread_host_count++); thread_host_ = std::make_shared<ThreadHost>(); if (is_background_view) { *thread_host_ = {thread_label, ThreadHost::Type::UI}; } else { *thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::RASTER | ThreadHost::Type::IO}; } ... fml::WeakPtr<PlatformViewAndroid> weak_platform_view; Shell::CreateCallback<PlatformView> on_create_platform_view = [is_background_view, &jni_facade, &weak_platform_view](Shell& shell) { std::unique_ptr<PlatformViewAndroid> platform_view_android; platform_view_android = std::make_unique<PlatformViewAndroid>( shell, shell.GetTaskRunners (), jni_facade, shell.GetSettings ().enable_software_rendering, !is_background_view ); weak_platform_view = platform_view_android->GetWeakPtr (); auto display = Display (jni_facade->GetDisplayRefreshRate ()); shell.OnDisplayUpdates (DisplayUpdateType::kStartup, {display}); return platform_view_android; }; Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) { return std::make_unique<Rasterizer>(shell); }; fml::MessageLoop::EnsureInitializedForCurrentThread (); fml::RefPtr<fml::TaskRunner> raster_runner; fml::RefPtr<fml::TaskRunner> ui_runner; fml::RefPtr<fml::TaskRunner> io_runner; fml::RefPtr<fml::TaskRunner> platform_runner = fml::MessageLoop::GetCurrent ().GetTaskRunner (); if (is_background_view) { auto single_task_runner = thread_host_->ui_thread->GetTaskRunner (); raster_runner = single_task_runner; ui_runner = single_task_runner; io_runner = single_task_runner; } else { raster_runner = thread_host_->raster_thread->GetTaskRunner (); ui_runner = thread_host_->ui_thread->GetTaskRunner (); io_runner = thread_host_->io_thread->GetTaskRunner (); } flutter::TaskRunners task_runners (thread_label, platform_runner, raster_runner, ui_runner, io_runner ) ; ... shell_ = Shell::Create (GetDefaultPlatformData (), task_runners, settings_, on_create_platform_view, on_create_rasterizer ); ... platform_view_ = weak_platform_view; FML_DCHECK (platform_view_); is_valid_ = shell_ != nullptr ; } void AndroidShellHolder::Launch (std::shared_ptr<AssetManager> asset_manager, const std::string& entrypoint, const std::string& libraryUrl) { if (!IsValid ()) { return ; } asset_manager_ = asset_manager; auto config = BuildRunConfiguration (asset_manager, entrypoint, libraryUrl); if (!config) { return ; } shell_->RunEngine (std::move (config.value ())); } ... fml::WeakPtr<PlatformViewAndroid> AndroidShellHolder::GetPlatformView () { FML_DCHECK (platform_view_); return platform_view_; }
Register
静态方法,用于动态注册JNI方法
继承自PlatformView
,并且构造函数包含PlatformView::Delegate
委托对象和PlatformViewAndroidJNI
对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class PlatformViewAndroid final : public PlatformView { public : static bool Register (JNIEnv* env) ; PlatformViewAndroid (PlatformView::Delegate& delegate, flutter::TaskRunners task_runners, std::shared_ptr<PlatformViewAndroidJNI> jni_facade, bool use_software_rendering, bool create_onscreen_surface); ... void DispatchPlatformMessage (JNIEnv* env, std::string name, jobject message_data, jint message_position, jint response_id) ; void HandlePlatformMessage (std::unique_ptr<flutter::PlatformMessage> message) override ; }
看一下具体的实现:
DispatchPlatformMessage
:将JNI传过来的数据转换成PlatformMessage
并转发给父类 的DispatchPlatformMessage
方法
HandlePlatformMessage
:通过JNI由Native调用Java方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 void PlatformViewAndroid::DispatchPlatformMessage (JNIEnv* env, std::string name, jobject java_message_data, jint java_message_position, jint response_id) { uint8_t * message_data = static_cast <uint8_t *>(env->GetDirectBufferAddress (java_message_data)); fml::MallocMapping message = fml::MallocMapping::Copy (message_data, java_message_position); fml::RefPtr<flutter::PlatformMessageResponse> response; if (response_id) { response = fml::MakeRefCounted<PlatformMessageResponseAndroid>( response_id, jni_facade_, task_runners_.GetPlatformTaskRunner ()); } PlatformView::DispatchPlatformMessage (std::make_unique<flutter::PlatformMessage>( std::move (name), std::move (message), std::move (response))); } void PlatformViewAndroid::HandlePlatformMessage ( std::unique_ptr<flutter::PlatformMessage> message) { int response_id = 0 ; if (auto response = message->response ()) { response_id = next_response_id_++; pending_responses_[response_id] = response; } jni_facade_->FlutterViewHandlePlatformMessage (std::move (message), response_id); message = nullptr ; }
PlatformView
是平台通用实现,不同平台的Embedder可以继承该类,定制一些自己的方法(一般是将数据格式转换为通用结构),再通过PlatformView
交给引擎处理。
摘取PlatformView部分声明函数
构造时传入委托对象,上文已经分析过,PlatformViewAndroid
创建用的委托对象就是shell/common/shell.cc
类
PlatformView
声明函数:创建RenderingSurface
,将输入事件、平台消息等发给Flutter处理等
委托类 的函数:基本和PlatformView
的函数对应
比较特殊的是HandlePlatformMessage
,这个函数是由Flutter引擎->委托Shell调用->PlatformView
,交给Android层处理的,因此没有委托方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 namespace flutter {class Shell ;class PlatformView { public : class Delegate { public : ... virtual void OnPlatformViewCreated (std::unique_ptr<Surface> surface) = 0 ; virtual void OnPlatformViewDestroyed () = 0 ; virtual void OnPlatformViewSetViewportMetrics ( const ViewportMetrics& metrics) = 0 ; virtual void OnPlatformViewDispatchPlatformMessage ( std::unique_ptr<PlatformMessage> message) = 0 ; virtual void OnPlatformViewDispatchPointerDataPacket ( std::unique_ptr<PointerDataPacket> packet) = 0 ; virtual void OnPlatformViewDispatchKeyDataPacket ( std::unique_ptr<KeyDataPacket> packet, std::function<void (bool )> callback) = 0 ; }; ... explicit PlatformView (Delegate& delegate, TaskRunners task_runners) ; void NotifyCreated () ; virtual void NotifyDestroyed () ; void SetViewportMetrics (const ViewportMetrics& metrics) ; void DispatchPlatformMessage (std::unique_ptr<PlatformMessage> message) ; virtual void HandlePlatformMessage (std::unique_ptr<PlatformMessage> message) ; void DispatchPointerDataPacket (std::unique_ptr<PointerDataPacket> packet) ; void DispatchKeyDataPacket (std::unique_ptr<KeyDataPacket> packet, Delegate::KeyDataResponse callback) ; void RegisterTexture (std::shared_ptr<flutter::Texture> texture) ; void UnregisterTexture (int64_t texture_id) ; ... protected : PlatformView::Delegate& delegate_; const TaskRunners task_runners_; PointerDataPacketConverter pointer_data_packet_converter_; SkISize size_; fml::WeakPtrFactory<PlatformView> weak_factory_; virtual std::unique_ptr<Surface> CreateRenderingSurface () ; private : FML_DISALLOW_COPY_AND_ASSIGN (PlatformView); }; } #endif
PlatformView
自身也不干活,而是交给委托对象处理,这个委托对象实际上就是Shell
1 2 3 4 5 6 7 8 9 10 11 12 PlatformView::PlatformView (Delegate& delegate, TaskRunners task_runners) : delegate_ (delegate), task_runners_ (std::move (task_runners)), size_ (SkISize::Make (0 , 0 )), weak_factory_ (this ) {} void PlatformView::DispatchPlatformMessage ( std::unique_ptr<PlatformMessage> message) { delegate_.OnPlatformViewDispatchPlatformMessage (std::move (message)); }
Shell Shell是嵌入层的壳,超出shell基本就到了引擎层,实现了多个组件Delegate
类,通过委托的方式将嵌入层的请求转发到引擎层,并且将引擎层的事件发到嵌入层。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Shell final : public PlatformView::Delegate, public Animator::Delegate, public Engine::Delegate, public Rasterizer::Delegate, public ServiceProtocol::Handler { ... static std::unique_ptr<Shell> Create ( const PlatformData& platform_data, TaskRunners task_runners, Settings settings, const CreateCallback<PlatformView>& on_create_platform_view, const CreateCallback<Rasterizer>& on_create_rasterizer, bool is_gpu_disabled = false ) ; void RunEngine (RunConfiguration run_configuration) ; bool Setup (std::unique_ptr<PlatformView> platform_view, std::unique_ptr<Engine> engine, std::unique_ptr<Rasterizer> rasterizer, std::unique_ptr<ShellIOManager> io_manager) ; ... std::unique_ptr<PlatformView> platform_view_; std::unique_ptr<Engine> engine_; std::unique_ptr<Rasterizer> rasterizer_; std::unique_ptr<ShellIOManager> io_manager_; }
Shell对象创建:Create-->CreateWithSnapshot-->CreateShellOnPlatformThread
创建DartVM
创建Shell对象
在GPU Runner中创建Rasterizer
:回调on_create_rasterizer
,传入shell委托对象
负责绘制Engine提交的LayerTree到Surface上
持有Surface和合成器上下文
在Platform Runner中创建PlatformView
:回调on_create_platform_view
,传入shell委托对象
在IO Runner中创建ShellIOManager
在UI Runner中创建Engine
:回调on_create_engine
,传入shell委托对象
调用Shell::Setup
将上面创建的几个对象保存到Shell中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 std::unique_ptr<Shell> Shell::Create (...) { ... auto vm_snapshot = DartSnapshot::VMSnapshotFromSettings (settings); auto isolate_snapshot = DartSnapshot::IsolateSnapshotFromSettings (settings); auto vm = DartVMRef::Create (settings, vm_snapshot, isolate_snapshot); FML_CHECK (vm) << "Must be able to initialize the VM." ; ... return CreateWithSnapshot (...); } std::unique_ptr<Shell> Shell::CreateWithSnapshot (...) { ... fml::AutoResetWaitableEvent latch; std::unique_ptr<Shell> shell; fml::TaskRunner::RunNowOrPostTask ( task_runners.GetPlatformTaskRunner (), fml::MakeCopyable ( ... shell = CreateShellOnPlatformThread (...); latch.Signal (); })); latch.Wait (); return shell; } std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread ( DartVMRef vm, TaskRunners task_runners, const PlatformData& platform_data, Settings settings, fml::RefPtr<const DartSnapshot> isolate_snapshot, const Shell::CreateCallback<PlatformView>& on_create_platform_view, const Shell::CreateCallback<Rasterizer>& on_create_rasterizer, const Shell::EngineCreateCallback& on_create_engine, bool is_gpu_disabled) { if (!task_runners.IsValid ()) { FML_LOG (ERROR) << "Task runners to run the shell were invalid." ; return nullptr ; } auto shell = std::unique_ptr<Shell>(new Shell (std::move (vm), task_runners, settings, std::make_shared<VolatilePathTracker>(task_runners.GetUITaskRunner (), !settings.skia_deterministic_rendering_on_cpu), is_gpu_disabled)); ... auto platform_view = on_create_platform_view (*shell.get ()); if (!platform_view || !platform_view->GetWeakPtr ()) { return nullptr ; } auto vsync_waiter = platform_view->CreateVSyncWaiter (); if (!vsync_waiter) { return nullptr ; } ... std::promise<std::unique_ptr<Engine>> engine_promise; auto engine_future = engine_promise.get_future (); fml::TaskRunner::RunNowOrPostTask ( shell->GetTaskRunners ().GetUITaskRunner (), fml::MakeCopyable ([...]() mutable { TRACE_EVENT0 ("flutter" , "ShellSetupUISubsystem" ); const auto & task_runners = shell->GetTaskRunners (); auto animator = std::make_unique<Animator>(*shell, task_runners, std::move (vsync_waiter)); engine_promise.set_value (on_create_engine (*shell,...)); })); if (!shell->Setup (std::move (platform_view), engine_future.get (), rasterizer_future.get (), io_manager_future.get ()) ) { return nullptr ; } return shell; }
小结
nativeRunBundleAndSnapshotFromLibrary 和上文一样查看Native调用流程,这里顺着搜索代码即可,就不贴源码了
关系梳理 嵌入层涉及到很多类,这里梳理一下它们之间引用和调用的关系,如下:
FlutterJNI
:Java和Native通信的统一入口
PlatformViewAndroidJNIImpl
:Native方法的核心实现
AndroidShellHolder
:作为C++层的主要入口,并且负责创建4个Runner线程
PlatformViewAndroid
:继承自PlatformView,加一些原生平台的特殊处理和转换后,交给父类执行,对父类功能进行扩充
PlatformView
:平台通用接口,负责沟通平台和Shell,没有具体的行为,基本都是委托给Shell处理
Shell
:平台通用实现,负责与引擎层交互
Engine
:引擎层主要入口,管理RootIsolate
,接收Layer渲染请求等
TaskRunners
:保存4个TaskRunner
ThreadHost
:创建线程
思考:Shell为什么不和PlatformView合并,而要通过PlatformView
委托调用Shell?
PlatformView接口是用来约束原生平台的实现
Shell是嵌入层和引擎层之间的门户,同时作为平台嵌入层和引擎层等的委托对象
组合优于继承:Shell是平台通用的,如果要添加平台特殊处理,PlatformViewAndroid
需要继承Shell,而Shell除了平台接口之外,还实现了引擎的委托接口,这一部分是不应该被继承的。
其他 FlutterInjector FlutterInjector
使用Builder创建FlutterLoader
和FlutterJNI
工厂对象,方便单元测试注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public final class FlutterInjector { public static final class Builder { private void fillDefaults () { if (flutterJniFactory == null ) { flutterJniFactory = new FlutterJNI.Factory(); } if (flutterLoader == null ) { flutterLoader = new FlutterLoader(flutterJniFactory.provideFlutterJNI()); } } } }
FlutterApplication 这里单独把FlutterApplication
拎出来介绍是因为这一步可有可无,在Application中加载是为了加快FlutterEngine
启动速度 。
注:由于应用可能不使用FlutterApplication
,因此FlutterEngine
初始化的时候还会再尝试加载资源
调用FlutterLoader
的startInitialization
方法进行初始化,异步加载Flutter资源。
1 2 3 4 5 6 7 8 9 public class FlutterApplication extends Application { @Override @CallSuper public void onCreate () { super .onCreate(); FlutterInjector.instance().flutterLoader().startInitialization(this ); } }
Flutter多线程 Flutter嵌入层中包含4个Runner:
Platform Runner:处理平台消息,调用Flutter Engine接口
UI Runner:执行Flutter Engine的Root Isolate代码,处理Widgets生成Layer Tree
GPU Runner(Raster Runner):负责GPU相关的管理和调度,UI Runner将构建的Layer Tree交给GPU Runner,GPU Runner中调用Skia引擎进行渲染
IO Runner:处理耗时操作,例如图片读取、压缩、渲染,可以向GPU Runner提交渲染请求
Platform Runner多个FlutterEngine共享,其他3个Runner引擎独立。
Runner不等同于线程,可以运行在同一线程,也可以运行在不同线程
Dart单线程 Dart默认是单线程处理任务,主线程有一个事件循环,包含两个事件队列:
microtask queue:自定义Task,优先执行,不应该执行耗时操作,否则会阻塞event队列事件,导致延迟
event queue:负责处理I/O、UI绘制、触摸事件等
async、await 协程语法糖,标记await方法,保存async方法上下文环境,事件循环的时候进行检查,如果执行完,则沿着离开的指针继续执行下面的代码。
async没有真正切换线程,因此无法执行耗时操作,会造成UI延迟
Isolate 切换线程需要创建Isolate,和Java线程区别在于线程间内存独立,需要通过Port和其他Isolate通信和交换数据(sendPort、receivePort)
结语 以Flutter工程方式为例,模块集成方式类似。源码分析比较枯燥,可以关注每个部分的小结和图片。
改了很多次,发现源码很深、结构比较乱,最终决定将Java层和Native层分开介绍,可能更利于阅读。
第一次分析C++的代码,style不是很习惯,很难像Java一样梳理类图关系。
参考资料: