Flutter Android启动源码分析(一)
前言
版本:Flutter 1.20.4 stable
这个系列主要讲解在Flutter的项目中,Android 从启动到加载Flutter等一系列的过程。
本文主要是对FlutterApplication的startInitialization方法及FlutterActivity整个类源码的分析
Application
public class FlutterApplication extends Application { @Override @CallSuper public void onCreate() { super.onCreate(); FlutterMain.startInitialization(this); }}
在Android项目的AndroidManifest.xml中指定了application为FlutterApplication,主要是一个初始化操作
最终会调用FlutterLoader类中的startInitialization方法
public void startInitialization(@NonNull Context applicationContext, @NonNull Settings settings) { if (this.settings != null) { return; } if (Looper.myLooper() != Looper.getMainLooper()) { throw new IllegalStateException("startInitialization must be called on the main thread"); } applicationContext = applicationContext.getApplicationContext(); this.settings = settings; long initStartTimestampMillis = SystemClock.uptimeMillis(); initConfig(applicationContext); initResources(applicationContext); System.loadLibrary("flutter"); VsyncWaiter.getInstance( (WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE)) .init(); long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis; FlutterJNI.nativeRecordStartTimestamp(initTimeMillis); }
- 加载Flutter引擎的本机库以启用后续的JNI调用
- 开始定位和打开应用程序APK中打包的Dart资源
FlutterApplication不 做过多分析,就是一些资源的初始化和so库加载的一些操作
FlutterActivity
class MainActivity : FlutterActivity(){}
public class FlutterActivity extends Activity implements FlutterActivityAndFragmentDelegate.Host, LifecycleOwner { public FlutterActivity() { lifecycle = new LifecycleRegistry(this); }
它是继承Activity并实现了FlutterActivityAndFragmentDelegate这个代理类中的Host接口及获取生命周期的LifecycleOwner接口
构造函数里实例化了一个LifecycleRegistry,它继承Lifecycle
public class LifecycleRegistry extends Lifecycle
然后实现LifecycleOwner接口的getLifecycle方法,返回了LifecycleRegistry对象,用于生命周期状态的监听和通知,这个不用过多介绍
@Override @NonNull public Lifecycle getLifecycle() { return lifecycle; }
onCreate方法
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { switchLaunchThemeForNormalTheme(); super.onCreate(savedInstanceState); lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); delegate = new FlutterActivityAndFragmentDelegate(this); delegate.onAttach(this); delegate.onActivityCreated(savedInstanceState); configureWindowForTransparency(); setContentView(createFlutterView()); configureStatusBarForFullscreenFlutterExperience(); }
@NonNull private View createFlutterView() { return delegate.onCreateView( null /* inflater */, null /* container */, null /* savedInstanceState */); }
对于主题和状态栏的设置我们不去关注,重点看一下configureWindowForTransparency这个方法和对FlutterActivityAndFragmentDelegate的一些操作
configureWindowForTransparency
如果FlutterActivity背景模式是透明(默认是不透明的模式),则设置整个FlutterActivity窗口透明及隐藏状态栏
其实如果我们不在原生项目中使用FlutterModule进行混合开发的话,是不需要关注这个方法的。因为默认就是非透明模式。
这里只是先提一嘴,后续讲到混合开发时会涉及到这个方法的一些配置
private void configureWindowForTransparency() { BackgroundMode backgroundMode = getBackgroundMode(); if (backgroundMode == BackgroundMode.transparent) { getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); } }
FlutterActivityAndFragmentDelegate
- 主要是实例化了FlutterActivityAndFragmentDelegate,传递FlutterActivityAndFragmentDelegate.Host实现类即当前类this
- 调用delegate.onAttach、onActivityCreated及onCreateView方法
- 关于FlutterActivityAndFragmentDelegate的介绍,我们放到下一篇文章里
其他生命周期方法大同小异,基本都是通过LifecycleRegistry.handleLifecycleEvent设置当前界面状态。然后将当前生命周期委托给delegate进行操作
@Override protected void onStart() { super.onStart(); lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START); delegate.onStart(); } @Override protected void onResume() { super.onResume(); lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_RESUME); delegate.onResume(); } @Override public void onPostResume() { super.onPostResume(); delegate.onPostResume(); } @Override protected void onPause() { super.onPause(); delegate.onPause(); lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE); }
接下来就是一些重写FlutterActivityAndFragmentDelegate.Host接口的方法
/* package */ interface Host extends SplashScreenProvider, FlutterEngineProvider, FlutterEngineConfigurator {
我们先看一下这个Host接口具体有哪些方法
下面根据其用途进行了一个大致的分类
-
获取Context、Activity、Lifecycle
方法名 描述 Context getContext(); 获取上下文对象 Activity getActivity(); 获取activity对象 Lifecycle getLifecycle(); 获取Lifecycle,返回的就是上面说的LifecycleRegistry -
实例化FlutterEngine
方法名 描述 String getCachedEngineId(); 缓存的FlutterEngine Id FlutterEngine provideFlutterEngine(@NonNull Context context); 提供一个FlutterEngine,目前版本返回null,暂不考虑 FlutterShellArgs getFlutterShellArgs(); 初始化参数 boolean shouldAttachEngineToActivity(); 建立Engine和Activity的连接关系,控制界面用于向附加到 FlutterEngine的插件提供Android资源和生命周期事件。 PlatformPlugin providePlatformPlugin( @Nullable Activity activity, @NonNull FlutterEngine flutterEngine); 提供一个PlatformPlugin(Android平台的插件实现) -
在FlutterView里首次运行Dart所需参数
方法名 描述 String getAppBundlePath(); 返回包含dart代码的app bundle 路径 String getInitialRoute(); 初始化路由路径 String getDartEntrypointFunctionName(); dart代码执行入口函数名称 -
实例化FlutterSplashView(启动界面及整个FlutterView)
方法名 描述 RenderMode getRenderMode(); Flutter UI 渲染模式,默认是surface TransparencyMode getTransparencyMode(); 透明度模式,默认是opaque void onFlutterSurfaceViewCreated(@NonNull FlutterSurfaceView flutterSurfaceView); FlutterSurfaceView创建回调 void onFlutterTextureViewCreated(@NonNull FlutterTextureView flutterTextureView); FlutterTextureView创建回调 void onFlutterUiDisplayed(); FlutterView首次渲染回调 void onFlutterUiNoLongerDisplayed(); FlutterView停止渲染回调 SplashScreen provideSplashScreen(); 返回一个SplashScreen 方法名 描述 boolean shouldDestroyEngineWithHost(); 是否清理engine
这里我们只对configureFlutterEngine方法实现做详细分析,剩余的在下篇文章中具体说明
configureFlutterEngine 插件注册方法
在FlutterActivityAndFragmentDelegate.onAttach方法中进行调用
void onAttach(@NonNull Context context) {// 省略部分代码 host.configureFlutterEngine(flutterEngine);}
FlutterActivity对其实现如下
@Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { registerPlugins(flutterEngine); } private static void registerPlugins(@NonNull FlutterEngine flutterEngine) { try { Class<?> generatedPluginRegistrant = Class.forName("io.flutter.plugins.GeneratedPluginRegistrant"); Method registrationMethod = generatedPluginRegistrant.getDeclaredMethod("registerWith", FlutterEngine.class); registrationMethod.invoke(null, flutterEngine); } catch (Exception e) { Log.w( TAG, "Tried to automatically register plugins with FlutterEngine (" + flutterEngine + ") but could not find and invoke the GeneratedPluginRegistrant."); } }
这里通过反射执行GeneratedPluginRegistrant.registerWith方法来注册pubspec.yaml中添加的插件依赖
@Keeppublic final class GeneratedPluginRegistrant { public static void registerWith(@NonNull FlutterEngine flutterEngine) { flutterEngine.getPlugins().add(new com.befovy.fijkplayer.FijkPlugin()); }}
registerWith方法中的 flutterEngine.getPlugins().add(xxx)无需我们手动添加,当执行pub get 时,如果含原生插件,则flutter会自动去添加,而且其实如果我们不注册自己的原生插件的话,这个方法其实也是不需要去做任何操作的。默认都是自动注册。这个方法及其业务逻辑在最近Flutter几个版本的更新中有很大的变化
如果我们要注册自己的原生插件,则需要在MainActivity中重写configureFlutterEngine并调用super.configureFlutterEngine,然后通过 flutterEngine.plugins.add方法进行注册
class MainActivity : FlutterActivity() { override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) // 原生封装的FlutterPlugin需要手动进行注册 flutterEngine.plugins.add(ToastPlugin()) }}
总结
通过本文我们可以学习到
- FlutterApplication主要做了哪些工作
- MainActivity继承的FlutterActivity主要做了哪些工作
以上内容如有不准确的地方,麻烦大家在评论区指出,我会一一改正
下篇文章会分析FlutterActivityAndFragmentDelegate这个代理类的一些逻辑,这个类比较关键,它是主要负责FlutterActivity和FlutterEngine、FlutterView、PlatformPlugin等一些联动工作,比如Engine注册、Dart执行、平台插件实现以及Activity和Engine生命周期的一些控制等等,同时会衍生出很多类。可以说这篇文章只是一个起点,核心业务在后面。
更多相关文章
- android EditText 不自动弹出键盘的方法
- Android(安卓)Studio ADB响应失败解决方法
- WindowManagerService添加View流程
- (备忘)Android(安卓)app中调用启动其他应用(系统应用和第三方应用)
- Android(安卓)四大组件,五大存储,六大布局
- (收集)ListView中常用属性
- Android下ContentProvider 学习总结
- 浅谈Java中Collections.sort对List排序的两种方法
- Python list sort方法的具体使用