概述
Flutter的启动包括Embedder、Engine、Framework三部分,本文仅描述Android平台的Embdder模块的启动流程。Flutter通常通过启动一个FlutterActivity启动,纯Flutter App则通过FlutterApplication启动。本文以后一种情况为例分析。
FlutterApplication#onCreate
// io/flutter/app/FlutterApplication.java
@Override
@CallSuper
public void onCreate() {
super.onCreate();
FlutterInjector.instance().flutterLoader().startInitialization(this);
}
实际是调用FlutterLoader#startInitialization
进行初始化。
FlutterLoader#startInitialization
public void startInitialization(@NonNull Context applicationContext) {
startInitialization(applicationContext, new Settings());
}
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");
}
final Context appContext = applicationContext.getApplicationContext();
this.settings = settings;
initStartTimestampMillis = SystemClock.uptimeMillis();
flutterApplicationInfo = ApplicationInfoLoader.load(appContext);
VsyncWaiter.getInstance((WindowManager) appContext.getSystemService(Context.WINDOW_SERVICE))
.init();
// Use a background thread for initialization tasks that require disk access.
Callable<InitResult> initTask =
new Callable<InitResult>() {
@Override
public InitResult call() {
ResourceExtractor resourceExtractor = initResources(appContext);
if (FlutterInjector.instance().shouldLoadNative()) {
System.loadLibrary("flutter");
}
// Prefetch the default font manager as soon as possible on a background thread.
// It helps to reduce time cost of engine setup that blocks the platform thread.
Executors.newSingleThreadExecutor()
.execute(
new Runnable() {
@Override
public void run() {
FlutterJNI.nativePrefetchDefaultFontManager();
}
});
if (resourceExtractor != null) {
resourceExtractor.waitForCompletion();
}
return new InitResult(
PathUtils.getFilesDir(appContext),
PathUtils.getCacheDirectory(appContext),
PathUtils.getDataDirectory(appContext));
}
};
initResultFuture = Executors.newSingleThreadExecutor().submit(initTask);
}
主要做了以下几件事:
检查是否在主线程
注册Vsync信号监听
启动一个异步任务,执行以下操作:
-
加载flutter engine
异步初始化字体管理器
加载asset目录下的资源
以上是Application会执行的操作,接着一般会进入一个FlutterActivity,那么依次查看其回调。
FlutterActivity#onCreate
// io/flutter/embedding/android/FlutterActivity.java
@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();
}
主要做了以下几件事:
从Splash切换成真正要显示的View
创建一个delegate,并触发对应回调
配置相关的窗口属性
创建一个新的FlutterView,作为Activity的ContentView
FlutterActivityAndFragmentDelegate#onAttach
void onAttach(@NonNull Context context) {
ensureAlive();
if (flutterEngine == null) {
setupFlutterEngine();
}
if (h