这里分析flutter作为module情况下Android端启动流程。
1.12.13版本通过下述方法启动Flutter页面。
startActivity(
FlutterActivity.createDefaultIntent(this)
)
createDefaultIntent()
public static Intent createDefaultIntent(@NonNull Context launchContext) {
return withNewEngine().build(launchContext);
}
public Intent build(@NonNull Context context) {
return new Intent(context, activityClass)
.putExtra(EXTRA_INITIAL_ROUTE, initialRoute)
.putExtra(EXTRA_BACKGROUND_MODE, backgroundMode)
.putExtra(EXTRA_DESTROY_ENGINE_WITH_ACTIVITY, true);
}
//activityClass声明处Class<? extends FlutterActivity>
//activityClass是FlutterActivity的子类型,接下来看FlutterActivity.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();
}
delegate.onAttach(this)
delegate.onActivityCreated(savedInstanceState)
FlutterActivityAndFragmentDelegate.onActivityCreated()
void onActivityCreated(@Nullable Bundle bundle) {
Log.v(TAG, "onActivityCreated. Giving plugins an opportunity to restore state.");
ensureAlive();
if (host.shouldAttachEngineToActivity()) {
flutterEngine.getActivityControlSurface().onRestoreInstanceState(bundle);
}
}
flutterEngine.getActivityControlSurface().onRestoreInstanceState最终调用到
FlutterEnginePluginRegistry.onRestoreInstanceState()
public void onRestoreInstanceState(@Nullable Bundle bundle) {
if (isAttachedToActivity()) {
activityPluginBinding.onRestoreInstanceState(bundle);
} else {
Log.e(TAG, "Attempted to notify ActivityAware plugins of onRestoreInstanceState, but no Activity was attached.");
}
}
activityPluginBinding.onRestoreInstanceState(bundle)
activityPluginBinding是FlutterEnginePluginRegistry的静态内部类FlutterEngineActivityPluginBinding
FlutterEngineActivityPluginBinding.onRestoreInstanceState()
遍历OnSaveInstanceStateListener集合回调onRestoreInstanceState()方法
void onRestoreInstanceState(@Nullable Bundle bundle) {
for (OnSaveInstanceStateListener listener : onSaveInstanceStateListeners) {
listener.onRestoreInstanceState(bundle);
}
}
onSaveInstanceStateListeners是FlutterEngineActivityPluginBinding成员变量
private final Set<OnSaveInstanceStateListener> onSaveInstanceStateListeners = new HashSet<>();
看看它在哪里被赋值,还是FlutterEngineActivityPluginBinding中
@Override
public void addOnSaveStateListener(@NonNull OnSaveInstanceStateListener listener) {
onSaveInstanceStateListeners.add(listener);
}
addOnSaveStateListener是ActivityPluginBinding接口方法
FlutterEngine通过FlutterEnginePluginRegistry注册一些PluginBinding同步对应组件的信息
ActivityPluginBinding中就有我们很熟悉的一些Activity回调
类似的FlutterEnginePluginRegistry中FlutterEngineServicePluginBinding实现了ServicePluginBinding接口
public interface ActivityPluginBinding {
@NonNull
Activity getActivity();
@NonNull
Object getLifecycle();
void addRequestPermissionsResultListener(@NonNull PluginRegistry.RequestPermissionsResultListener listener);
void removeRequestPermissionsResultListener(@NonNull PluginRegistry.RequestPermissionsResultListener listener);
void addActivityResultListener(@NonNull PluginRegistry.ActivityResultListener listener);
void removeActivityResultListener(@NonNull PluginRegistry.ActivityResultListener listener);
void addOnNewIntentListener(@NonNull PluginRegistry.NewIntentListener listener);
void removeOnNewIntentListener(@NonNull PluginRegistry.NewIntentListener listener);
void addOnUserLeaveHintListener(@NonNull PluginRegistry.UserLeaveHintListener listener);
void removeOnUserLeaveHintListener(@NonNull PluginRegistry.UserLeaveHintListener listener);
void addOnSaveStateListener(@NonNull OnSaveInstanceStateListener listener);
void removeOnSaveStateListener(@NonNull OnSaveInstanceStateListener listener);
interface OnSaveInstanceStateListener {
void onSaveInstanceState(@NonNull Bundle bundle);
void onRestoreInstanceState(@Nullable Bundle bundle);
}
}
FlutterActivityAndFragmentDelegate.onAttach()
void onAttach(@NonNull Context context) {
ensureAlive();
if (flutterEngine == null) {
setupFlutterEngine();
}
platformPlugin = host.providePlatformPlugin(host.getActivity(), flutterEngine);
if (host.shouldAttachEngineToActivity()) {
//FlutterEnginePluginRegistry.attachToActivity()
flutterEngine.getActivityControlSurface().attachToActivity(
host.getActivity(),
host.getLifecycle()
);
}
host.configureFlutterEngine(flutterEngine);
}
ensureAlive()
private void ensureAlive() {
//host是前面delegate = new FlutterActivityAndFragmentDelegate(this)传入的this即FlutterActivity
if (host == null) {
throw new IllegalStateException("Cannot execute method on a destroyed FlutterActivityAndFragmentDelegate.");
}
}
setupFlutterEngine()
void setupFlutterEngine() {
String cachedEngineId = host.getCachedEngineId();
if (cachedEngineId != null) {
//flutterEngine缓存池
flutterEngine = FlutterEngineCache.getInstance().get(cachedEngineId);
isFlutterEngineFromHost = true;
if (flutterEngine == null) {
throw new IllegalStateException("The requested cached FlutterEngine did not exist in the FlutterEngineCache: '" + cachedEngineId + "'");
}
return;
}
flutterEngine = host.provideFlutterEngine(host.getContext());
if (flutterEngine != null) {
isFlutterEngineFromHost = true;
return;
}
//初始化FlutterEngine
flutterEngine = new FlutterEngine(host.getContext(), host.getFlutterShellArgs().toArray());
isFlutterEngineFromHost = false;
}
FlutterEngine()
public FlutterEngine(@NonNull Context context, @Nullable String[] dartVmArgs) {
this(context, FlutterLoader.getInstance(), new FlutterJNI(), dartVmArgs, true);
}
public FlutterEngine(
@NonNull Context context,
@NonNull FlutterLoader flutterLoader,
@NonNull FlutterJNI flutterJNI,
@Nullable String[] dartVmArgs,
boolean automaticallyRegisterPlugins
) {
this.flutterJNI = flutterJNI;
flutterLoader.startInitialization(context);
flutterLoader.ensureInitializationComplete(context, dartVmArgs);
flutterJNI.addEngineLifecycleListener(engineLifecycleListener);
attachToJni();
this.dartExecutor = new DartExecutor(flutterJNI, context.getAssets());
this.dartExecutor.onAttachedToJNI();
this.renderer = new FlutterRenderer(flutterJNI);
accessibilityChannel = new AccessibilityChannel(dartExecutor, flutterJNI);
keyEventChannel = new KeyEventChannel(dartExecutor);
lifecycleChannel = new LifecycleChannel(dartExecutor);
localizationChannel = new LocalizationChannel(dartExecutor);
navigationChannel = new NavigationChannel(dartExecutor);
platformChannel = new PlatformChannel(dartExecutor);
settingsChannel = new SettingsChannel(dartExecutor);
systemChannel = new SystemChannel(dartExecutor);
textInputChannel = new TextInputChannel(dartExecutor);
platformViewsController = new PlatformViewsController();
this.pluginRegistry = new FlutterEnginePluginRegistry(
context.getApplicationContext(),
this,
flutterLoader
);
if (automaticallyRegisterPlugins) {
registerPlugins();
}
}
flutterLoader.startInitialization(context)
flutterLoader.ensureInitializationComplete(context, dartVmArgs)
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");
}
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);
}
//initConfig 初始化资源文件
private void initConfig(@NonNull Context applicationContext) {
Bundle metadata = getApplicationInfo(applicationContext).metaData;
if (metadata == null) {
return;
}
//so包名称
aotSharedLibraryName = metadata.getString(PUBLIC_AOT_SHARED_LIBRARY_NAME, DEFAULT_AOT_SHARED_LIBRARY_NAME);
//flutterAsset
flutterAssetsDir = metadata.getString(PUBLIC_FLUTTER_ASSETS_DIR_KEY, DEFAULT_FLUTTER_ASSETS_DIR);
//BuildConfig.DEBUG || BuildConfig.JIT_RELEASE使用,AOT Release版本flutter代码打包成so包。
//ensureInitializationComplete()中可以验证
vmSnapshotData = metadata.getString(PUBLIC_VM_SNAPSHOT_DATA_KEY, DEFAULT_VM_SNAPSHOT_DATA);
isolateSnapshotData = metadata.getString(PUBLIC_ISOLATE_SNAPSHOT_DATA_KEY, DEFAULT_ISOLATE_SNAPSHOT_DATA);
}
//initResources 初始化资源,方法名自解释。
private void initResources(@NonNull Context applicationContext) {
new ResourceCleaner(applicationContext).start();
if (BuildConfig.DEBUG || BuildConfig.JIT_RELEASE) {
final String dataDirPath = PathUtils.getDataDirectory(applicationContext);
final String packageName = applicationContext.getPackageName();
final PackageManager packageManager = applicationContext.getPackageManager();
final AssetManager assetManager = applicationContext.getResources().getAssets();
resourceExtractor = new ResourceExtractor(dataDirPath, packageName, packageManager, assetManager);
resourceExtractor
.addResource(fullAssetPathFrom(vmSnapshotData))
.addResource(fullAssetPathFrom(isolateSnapshotData))
.addResource(fullAssetPathFrom(DEFAULT_KERNEL_BLOB));
resourceExtractor.start();
}
}
ensureInitializationComplete()
public void ensureInitializationComplete(@NonNull Context applicationContext, @Nullable String[] args) {
if (initialized) {
return;
}
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("ensureInitializationComplete must be called on the main thread");
}
if (settings == null) {
throw new IllegalStateException("ensureInitializationComplete must be called after startInitialization");
}
try {
if (resourceExtractor != null) {
resourceExtractor.waitForCompletion();
}
List<String> shellArgs = new ArrayList<>();
shellArgs.add("--icu-symbol-prefix=_binary_icudtl_dat");
ApplicationInfo applicationInfo = getApplicationInfo(applicationContext);
shellArgs.add("--icu-native-lib-path=" + applicationInfo.nativeLibraryDir + File.separator + DEFAULT_LIBRARY);
if (args != null) {
Collections.addAll(shellArgs, args);
}
String kernelPath = null;
//DEBUG/JIT_RELEASE加载逻辑
if (BuildConfig.DEBUG || BuildConfig.JIT_RELEASE) {
String snapshotAssetPath = PathUtils.getDataDirectory(applicationContext) + File.separator + flutterAssetsDir;
kernelPath = snapshotAssetPath + File.separator + DEFAULT_KERNEL_BLOB;
shellArgs.add("--" + SNAPSHOT_ASSET_PATH_KEY + "=" + snapshotAssetPath);
shellArgs.add("--" + VM_SNAPSHOT_DATA_KEY + "=" + vmSnapshotData);
shellArgs.add("--" + ISOLATE_SNAPSHOT_DATA_KEY + "=" + isolateSnapshotData);
} else {//AOT Release加载逻辑
shellArgs.add("--" + AOT_SHARED_LIBRARY_NAME + "=" + aotSharedLibraryName);
//热更新可指定AOT_SHARED_LIBRARY_NAME为hotfix.so地址
//hotfix.so拷贝到data/data/package/app_libs/目录下
shellArgs.add("--" + AOT_SHARED_LIBRARY_NAME + "=" + applicationInfo.nativeLibraryDir + File.separator + aotSharedLibraryName);
}
shellArgs.add("--cache-dir-path=" + PathUtils.getCacheDirectory(applicationContext));
if (settings.getLogTag() != null) {
shellArgs.add("--log-tag=" + settings.getLogTag());
}
String appStoragePath = PathUtils.getFilesDir(applicationContext);
String engineCachesPath = PathUtils.getCacheDirectory(applicationContext);
FlutterJNI.nativeInit(applicationContext, shellArgs.toArray(new String[0]),
kernelPath, appStoragePath, engineCachesPath);
initialized = true;
} catch (Exception e) {
Log.e(TAG, "Flutter initialization failed.", e);
throw new RuntimeException(e);
}
}
shellArgs.add("--" + AOT_SHARED_LIBRARY_NAME + "=" + aotSharedLibraryName)
shellArgs是个数组,包含so包和资源文件,最终调用FlutterJNI.nativeInit()加载flutter资源。
实现热更新可以从这个数组入手。
网友评论