新建一个Flutter工程,android模块。
1,只有一个Activity组件,它是Dart层绘制Widget的容器。
2,Application配置FlutterApplication。
一、Application初始化
<application
android:name="io.flutter.app.FlutterApplication"
android:label="flutter_app"
android:icon="@mipmap/ic_launcher">
</application>
应用Application配置io.flutter.app.FlutterApplication类,App首次启动时,初始化。
@CallSuper
public void onCreate() {
super.onCreate();
FlutterMain.startInitialization(this);
}
调用FlutterMain.startInitialization()方法。
public static void startInitialization(@NonNull Context applicationContext, @NonNull FlutterMain.Settings settings) {
if (!isRunningInRobolectricTest) {
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("startInitialization must be called on the main thread");
} else if (sSettings == null) {
sSettings = settings;
initConfig(applicationContext);
initResources(applicationContext);
System.loadLibrary("flutter");
...
}
}
}
initConfig方法,从AndroidManfest.xml配置的applicaion节点获取meta-data数据,初始化以下默认值。
private static String sAotSharedLibraryName = "libapp.so";
private static String sVmSnapshotData = "vm_snapshot_data";
private static String sIsolateSnapshotData = "isolate_snapshot_data";
private static String sFlutterAssetsDir = "flutter_assets";
这些值都是使用中用到的name,例如,抽取apk中asset资源时,flutter_assets打包目录,打包产物data名称。
initResources方法,初始化资源。
在Flutter打包apk的asset目录下,包括fluttter_asset目录/资源项,将资源从apk中抽取,保存在Context.getDir("flutter", 0)
目录下。
/data/user/0/包名/app_flutter目录。
在目录中创建一个时间戳文件,根据apk版本和包信息记录的lastUpdateTime更新时间,第二次启动时,若apk未更新,不需要再次抽取。
加载so库,libflutter.so,System.loadLibrary()。
二、组件初始化(Android)
主页面继承FlutterActivity,配置启动模式singleTop。
public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
}
}
FlutterActivity类在io.flutter.app包,(区别io.flutter.embedding.android包),组件生命周期委托给FlutterActivityDelegate类。
public void onCreate(Bundle savedInstanceState) {
...
String[] args = getArgsFromIntent(this.activity.getIntent());
FlutterMain.ensureInitializationComplete(this.activity.getApplicationContext(), args);
this.flutterView = this.viewFactory.createFlutterView(this.activity);
if (this.flutterView == null) {
FlutterNativeView nativeView = this.viewFactory.createFlutterNativeView();
this.flutterView = new FlutterView(this.activity, (AttributeSet)null, nativeView);
this.flutterView.setLayoutParams(matchParent);
this.activity.setContentView(this.flutterView);
...
}
if (!this.loadIntent(this.activity.getIntent())) {
String appBundlePath = FlutterMain.findAppBundlePath();
if (appBundlePath != null) {
this.runBundle(appBundlePath);
}
}
}
组件启动,onCreate方法。
FlutterMain.ensureInitializationComplete方法,确保资源成功抽取完成,创建FlutterView视图(io.flutter.view),继承SurfaceView类,setContentView方法,设置组件主布局即FlutterView视图。
最后,根据Bundle路径,runBundle()加载运行,
调用FlutterView的runFromBundle方法,入口点在dart的main方法,
通过FlutterNativeView,调用FlutterJNI的native方法。
nativeRunBundleAndSnapshotFromLibrary方法。
任重而道远
网友评论