Flutter Android启动源码分析(一)
前言
版本:Flutter 1.20.4 stable
这个系列主要讲解在Flutter的项目中,Android 从启动到加载Flutter等一系列的过程。
本文主要是对FlutterApplication的startInitialization方法及FlutterActivity整个类源码的分析
Application
<application
android:name="io.flutter.app.FlutterApplication"
android:label="flutter_channel"
android:icon="@mipmap/ic_launcher">
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中添加的插件依赖
@Keep
public 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生命周期的一些控制等等,同时会衍生出很多类。可以说这篇文章只是一个起点,核心业务在后面。
本文地址:https://blog.csdn.net/fighting_android/article/details/108700276
上一篇: 什么是webview?用在哪里?
下一篇: C/C++中虚函数详解及其作用介绍
推荐阅读
-
android的消息处理机制(图文+源码分析)—Looper/Handler/Message
-
Android Handler主线程和一般线程通信的应用分析
-
go开源项目influxdb-relay源码分析(一)
-
Android判断程序是否第一次启动
-
vuex 源码分析(一) 使用方法和代码结构
-
Android 自定义相机及分析源码
-
kubernetes垃圾回收器GarbageCollector源码分析(一)
-
Netty源码分析 (三)----- 服务端启动源码分析
-
Android 中启动自己另一个程序的activity如何实现
-
Android 启动另一个App/apk中的Activity实现代码