前言
本篇分析基于flutter 2.5.1源码
Flutter 2.5.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision ffb2ecea52 (6 months ago) • 2021-09-17 15:26:33 -0400
Engine • revision b3af521a05
Tools • Dart 2.14.2
复制代码
一.FLutterPlugin的启动过程
1.1 FlutterActivity启动
- 一般情况下,我们会继承FlutterActivity作为我们的flutter页面元素的承载者。比如FLutterboostActivity.
- 启动activity执行onCreate方法
protected void onCreate(@Nullable Bundle savedInstanceState) {
switchLaunchThemeForNormalTheme();
super.onCreate(savedInstanceState);
delegate = new FlutterActivityAndFragmentDelegate(this);
delegate.onAttach(this);
delegate.onRestoreInstanceState(savedInstanceState);
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
configureWindowForTransparency();
setContentView(createFlutterView());
configureStatusBarForFullscreenFlutterExperience();
}
复制代码
1.2 FlutterActivityAndFragmentDelegate.onAttach
它的作用有两个
- 初始化FlutterEngine
- 注册插件,这里的host实际上就是FLutterActivity或者FlutterFragment
void onAttach(@NonNull Context context) {
ensureAlive();
if (flutterEngine == null) {
setupFlutterEngine();
}
if (host.shouldAttachEngineToActivity()) {
Log.v(TAG, "Attaching FlutterEngine to the Activity that owns this delegate.");
flutterEngine.getActivityControlSurface().attachToActivity(this, host.getLifecycle());
}
platformPlugin = host.providePlatformPlugin(host.getActivity(), flutterEngine);
host.configureFlutterEngine(flutterEngine);
}
复制代码
1.3 FlutterActivityAndFragmentDelegate.setupFlutterEngine
- 采用缓存的flutterEngine或者构造新的flutterEngine
- flutterEngine 是dart代码的运行时环境,初始化了常用的darvm到jvm的channel,用于渲染的flutterRender等。
- isFlutterEngineFromHost注意这个,它表示flutterEngine是从已有的FlutterActivity共享的还是重新创建的。
void setupFlutterEngine() {
Log.v(TAG, "Setting up FlutterEngine.");
// First, check if the host wants to use a cached FlutterEngine.
String cachedEngineId = host.getCachedEngineId();
if (cachedEngineId != null) {
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;
}
// Second, defer to subclasses for a custom FlutterEngine.
flutterEngine = host.provideFlutterEngine(host.getContext());
if (flutterEngine != null) {
isFlutterEngineFromHost = true;
return;
}
// Our host did not provide a custom FlutterEngine. Create a FlutterEngine to back our
// FlutterView.
Log.v(
TAG,
"No preferred FlutterEngine was provided. Creating a new FlutterEngine for"
+ " this FlutterFragment.");
flutterEngine =
new FlutterEngine(
host.getContext(),
host.getFlutterShellArgs().toArray(),
/*automaticallyRegisterPlugins=*/ false,
/*willProvideRestorationData=*/ host.shouldRestoreAndSaveState());
isFlutterEngineFromHost = false;
}
复制代码
1.4 FlutterEngine
public FlutterEngine(
@NonNull Context context,
@Nullable FlutterLoader flutterLoader,
@NonNull FlutterJNI flutterJNI,
@NonNull PlatformViewsController platformViewsController,
@Nullable String[] dartVmArgs,
boolean automaticallyRegisterPlugins,
boolean waitForRestorationData) {
AssetManager assetManager;
try {
assetManager = context.createPackageContext(context.getPackageName(), 0).getAssets();
} catch (NameNotFoundException e) {
assetManager = context.getAssets();
}
FlutterInjector injector = FlutterInjector.instance();
if (flutterJNI == null) {
flutterJNI = injector.getFlutterJNIFactory().provideFlutterJNI();
}
this.flutterJNI = flutterJNI;
this.dartExecutor = new DartExecutor(flutterJNI, assetManager);
this.dartExecutor.onAttachedToJNI();
DeferredComponentManager deferredComponentManager =
FlutterInjector.instance().deferredComponentManager();
accessibilityChannel = new AccessibilityChannel(dartExecutor, flutterJNI);
deferredComponentChannel = new DeferredComponentChannel(dartExecutor);
keyEventChannel = new KeyEventChannel(dartExecutor);
lifecycleChannel = new LifecycleChannel(dartExecutor);
localizationChannel = new LocalizationChannel(dartExecutor);
mouseCursorChannel = new MouseCursorChannel(dartExecutor);
navigationChannel = new NavigationChannel(dartExecutor);
platformChannel = new PlatformChannel(dartExecutor);
restorationChannel = new RestorationChannel(dartExecutor, waitForRestorationData);
settingsChannel = new SettingsChannel(dartExecutor);
systemChannel = new SystemChannel(dartExecutor);
textInputChannel = new TextInputChannel(dartExecutor);
if (deferredComponentManager != null) {
deferredComponentManager.setDeferredComponentChannel(deferredComponentChannel);
}
this.localizationPlugin = new LocalizationPlugin(context, localizationChannel);
if (flutterLoader == null) {
flutterLoader = injector.flutterLoader();
}
if (!flutterJNI.isAttached()) {
flutterLoader.startInitialization(context.getApplicationContext());
flutterLoader.ensureInitializationComplete(context, dartVmArgs);
}
flutterJNI.addEngineLifecycleListener(engineLifecycleListener);
flutterJNI.setPlatformViewsController(platformViewsController);
flutterJNI.setLocalizationPlugin(localizationPlugin);
flutterJNI.setDeferredComponentManager(injector.deferredComponentManager());
// It should typically be a fresh, unattached JNI. But on a spawned engine, the JNI instance
// is already attached to a native shell. In that case, the Java FlutterEngine is created around
// an existing shell.
if (!flutterJNI.isAttached()) {
attachToJni();
}
// TODO(mattcarroll): FlutterRenderer is temporally coupled to attach(). Remove that coupling if
// possible.
this.renderer = new FlutterRenderer(flutterJNI);
this.platformViewsController = platformViewsController;
this.platformViewsController.onAttachedToJNI();
this.pluginRegistry =
new FlutterEngineConnectionRegistry(context.getApplicationContext(), this, flutterLoader);
// Only automatically register plugins if both constructor parameter and
// loaded AndroidManifest config turn this feature on.
if (automaticallyRegisterPlugins && flutterLoader.automaticallyRegisterPlugins()) {
GeneratedPluginRegister.registerGeneratedPlugins(this);
}
}
复制代码
如果是自动注册plugins,则触发plugins的注册流程,默认情况下为false
1.5 FlutterActivityAndFragmentDelegate.Host.configureFlutterEngine
如果是复用的FlutterEngine,则不重复初始化plugins。一般第一次启动FlutterAcitivity时isFlutterEngineFromHost=false此时执行registerGeneratedPlugins
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
if (delegate.isFlutterEngineFromHost()) {
return;
}
GeneratedPluginRegister.registerGeneratedPlugins(flutterEngine);
}
复制代码
1.6 GeneratedPluginRegister.registerGeneratedPlugins
public static void registerGeneratedPlugins(@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.e(
TAG,
"Tried to automatically register plugins with FlutterEngine ("
+ flutterEngine
+ ") but could not find or invoke the GeneratedPluginRegistrant.");
Log.e(TAG, "Received exception while registering", e);
}
}
复制代码
通过反射的形式找到自动生成的GeneratedPluginRegistrant类,调用其静态方法registerWith
1.7 GeneratedPluginRegistrant.registerWith
public final class GeneratedPluginRegistrant {
private static final String TAG = "GeneratedPluginRegistrant";
public static void registerWith(@NonNull FlutterEngine flutterEngine) {
try {
flutterEngine.getPlugins().add(new io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin());
} catch(Exception e) {
Log.e(TAG, "Error registering plugin flutter_plugin_android_lifecycle, io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin", e);
}
try {
flutterEngine.getPlugins().add(new com.huya.flutterbridge.FlutterbridgePlugin());
} catch(Exception e) {
Log.e(TAG, "Error registering plugin flutterbridge, com.huya.flutterbridge.FlutterbridgePlugin", e);
}
...
}
}
复制代码
将所有由pubspec.yaml中引入的插件,注册到插件管理器中
dependencies:
image_picker: ^0.8.4
video_player: ^2.1.14
webview_flutter: ^2.0.12
复制代码
1.8 FlutterEngineConnectionRegistry.add
public void add(@NonNull FlutterPlugin plugin) {
plugins.put(plugin.getClass(), plugin);
plugin.onAttachedToEngine(pluginBinding);
if (plugin instanceof ActivityAware) {
ActivityAware activityAware = (ActivityAware) plugin;
activityAwarePlugins.put(plugin.getClass(), activityAware);
if (isAttachedToActivity()) {
activityAware.onAttachedToActivity(activityPluginBinding);
}
}
if (plugin instanceof ServiceAware) {
ServiceAware serviceAware = (ServiceAware) plugin;
serviceAwarePlugins.put(plugin.getClass(), serviceAware);
if (isAttachedToService()) {
serviceAware.onAttachedToService(servicePluginBinding);
}
}
if (plugin instanceof BroadcastReceiverAware) {
BroadcastReceiverAware broadcastReceiverAware = (BroadcastReceiverAware) plugin;
broadcastReceiverAwarePlugins.put(plugin.getClass(), broadcastReceiverAware);
if (isAttachedToBroadcastReceiver()) {
broadcastReceiverAware.onAttachedToBroadcastReceiver(broadcastReceiverPluginBinding);
}
}
if (plugin instanceof ContentProviderAware) {
ContentProviderAware contentProviderAware = (ContentProviderAware) plugin;
contentProviderAwarePlugins.put(plugin.getClass(), contentProviderAware);
if (isAttachedToContentProvider()) {
contentProviderAware.onAttachedToContentProvider(contentProviderPluginBinding);
}
}
}
复制代码
- 首先触发了plugin.onAttachedToEngine方法回调
- 将plugin按照类型分别加入到不同的map中,比如将实现了ActivityAware的插件加入到activityAwarePlugins中。
FlutterEngineConnectionRegistry.attachToActivity
public void attachToActivity(@NonNull Activity activity, @NonNull Lifecycle lifecycle) {
Log.v(
TAG,
"Attaching to an Activity: "
+ activity
+ "."
+ (isWaitingForActivityReattachment ? " This is after a config change." : ""));
if (this.exclusiveActivity != null) {
this.exclusiveActivity.detachFromFlutterEngine();
}
// If we were already attached to an app component, detach from it.
detachFromAppComponent();
if (this.exclusiveActivity != null) {
throw new AssertionError("Only activity or exclusiveActivity should be set");
}
this.activity = activity;
attachToActivityInternal(activity, lifecycle);
}
private void attachToActivityInternal(@NonNull Activity activity, @NonNull Lifecycle lifecycle) {
this.activityPluginBinding = new FlutterEngineActivityPluginBinding(activity, lifecycle);
// Activate the PlatformViewsController. This must happen before any plugins attempt
// to use it, otherwise an error stack trace will appear that says there is no
// flutter/platform_views channel.
flutterEngine
.getPlatformViewsController()
.attach(activity, flutterEngine.getRenderer(), flutterEngine.getDartExecutor());
// Notify all ActivityAware plugins that they are now attached to a new Activity.
for (ActivityAware activityAware : activityAwarePlugins.values()) {
if (isWaitingForActivityReattachment) {
activityAware.onReattachedToActivityForConfigChanges(activityPluginBinding);
} else {
activityAware.onAttachedToActivity(activityPluginBinding);
}
}
isWaitingForActivityReattachment = false;
}
复制代码
这里会遍历activityAwarePlugins中的插件,回调生命周期方法onAttachedToActivity,其他的生命周期方法依次类推 。
二.plugin的定义
flutter工具提供了自定义插件的方法
flutter create --org com.xxx --template=plugin --platforms=android,ios -a java -i swift flutterbridge
复制代码
新建出来的项目在pubspec.yaml中会定义插件的信息
flutter:
uses-material-design: true
assets:
- lib/HiveBusiness/assets/
plugin:
platforms:
android:
package: com.xxx.flutterbridge
pluginClass: FlutterbridgePlugin
ios:
pluginClass: FlutterbridgePlugin
复制代码
2.1 FlutterbridgePlugin
定义plugin的目的是为了做dartvm和native的通信,也同时提供一些native能力。
一般我们需要处理两件事
- plugin中处理生命周期方法,主要是在onAttachedToEngine的时候做初始化
- 将native的能力封装成channel通信参数提交给dart侧使用。
关于如何定义一个完整的的插件,后续篇幅分析。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END