首先手动创建一个hello_project的Flutter Project,再一步步跟着源码走
按照惯例我们首先查找是否有自定义的Application,发现Flutter Project没有自定义Application,然后我们再来看MainActivity.kt
class MainActivity: FlutterActivity() {
}
MainActivity代码无比简单,我们继续看FlutterActivity.java(Google官方都推Kotlin了,FlutterActivity居然还用Java…)
public class FlutterActivity extends Activity
implements FlutterActivityAndFragmentDelegate.Host, LifecycleOwner
MainActivity直接继承自Activity,同时实现了两个接口:LifecycleOwner(暴露绑定生命周期的方法),FlutterActivityAndFragmentDelegate.Host,这里的Host主要是FlutterActivity作为宿主提供暴露各种方法,Host接口方法命名都比较简单直观,这里不做详细解释。
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
switchLaunchThemeForNormalTheme();
super.onCreate(savedInstanceState);
// 创建delegate,重点后面分析
delegate = new FlutterActivityAndFragmentDelegate(this);
// 1、onAttach 重点,内部初始化引擎逻辑
delegate.onAttach(this);
//onRestoreInstanceState,类似Activity中的onRestoreInstanceState方法,可以用来恢复数据
delegate.onRestoreInstanceState(savedInstanceState);
//绑定生命周期
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
configureWindowForTransparency();
//2、创建FlutterView,显示到Activity上
setContentView(createFlutterView());
configureStatusBarForFullscreenFlutterExperience();
}
这里我们重点关注两步
下面着重一步一步来分析
void onAttach(@NonNull Context context) {
ensureAlive();
// 是否已经初始化过引擎
if (flutterEngine == null) {
//下面重点分析引擎初始化
setupFlutterEngine();
}
if (host.shouldAttachEngineToActivity()) {
//engine 与 activity绑定
Log.v(TAG, "Attaching FlutterEngine to the Activity that owns this delegate.");
flutterEngine.getActivityControlSurface().attachToActivity(this, host.getLifecycle());
}
//初始化平台插件,本质上,是将engine的 channel回调与平台的系统服务进行绑定,如:震动、复制粘贴、声音播放等...
platformPlugin = host.providePlatformPlugin(host.getActivity(), flutterEngine);
//注册插件,通过反射调用 “io.flutter.plugins.GeneratedPluginRegistrant.registerWith()”
host.configureFlutterEngine(flutterEngine);
}
@VisibleForTesting
void setupFlutterEngine() {
// 返回FlutterEngine,如果为空会自动创建一个Engine
flutterEngine = host.provideFlutterEngine(host.getContext());
if (flutterEngine != null) {
isFlutterEngineFromHost = true;
return;
}
// 如果上面步骤都没后获取到flutterEngine的话,就创建一个FlutterEngine
flutterEngine =
new FlutterEngine(
host.getContext(),
host.getFlutterShellArgs().toArray(),
/*automaticallyRegisterPlugins=*/ false,
/*willProvideRestorationData=*/ host.shouldRestoreAndSaveState());
isFlutterEngineFromHost = false;
}
我们先来看一下FlutterEngine的理解:
最终整理对于一个多FlutterEngine的App来说,FlutterEngine,DartExecutor,Dart VM, Isloate关系如下:
接下来我们继续看FlutterEngine
public class FlutterEngine {
//Flutter C/C++与平台java层接口定义交互。Flutter 的引擎是用 C/C++ 构建的。 Android Flutter 嵌入负责协调 Android 操作系统事件和应用程序用户与 C/C++ 引擎的交互。
@NonNull private final FlutterJNI flutterJNI;
//表示 FlutterEngine 的渲染职责。
//FlutterRenderer 与提供的 RenderSurface 协同工作,将 Flutter 像素绘制到 Android 视图层次结构。
//FlutterRenderer 管理用于渲染的纹理,并通过 JNI 将一些 Java 调用转发到原生 Flutter 代码。 相应的 RenderSurface 提供此渲染器绘制的 Android Surface。
//io.flutter.embedding.android.FlutterSurfaceView 和 io.flutter.embedding.android.FlutterTextureView 是 RenderSurface 的实现
@NonNull private final FlutterRenderer renderer;
//Dart执行器。
@NonNull private final DartExecutor dartExecutor;
//用来管理安卓组件和Flutter plugins插件。
@NonNull private final FlutterEngineConnectionRegistry pluginRegistry;
//localization的安卓端实现插件。
@NonNull private final LocalizationPlugin localizationPlugin;
//一堆系统通道。负责与系统底层通信
@NonNull private final AccessibilityChannel accessibilityChannel;
@NonNull private final DeferredComponentChannel deferredComponentChannel;
@NonNull private final KeyEventChannel keyEventChannel;
@NonNull private final LifecycleChannel lifecycleChannel;
@NonNull private final LocalizationChannel localizationChannel;
@NonNull private final MouseCursorChannel mouseCursorChannel;
@NonNull private final NavigationChannel navigationChannel;
@NonNull private final RestorationChannel restorationChannel;
@NonNull private final PlatformChannel platformChannel;
@NonNull private final SettingsChannel settingsChannel;
@NonNull private final SystemChannel systemChannel;
@NonNull private final TextInputChannel textInputChannel;
// Platform Views.
// 管理平台视图。每个 io.flutter.app.FlutterPluginRegistry 都有一个平台视图控制器。 一个平台视图控制器最多可以附加到一个 Flutter 视图
@NonNull private final PlatformViewsController platformViewsController;
// Engine Lifecycle.
// 引擎声明周期监听
@NonNull private final Set<EngineLifecycleListener> engineLifecycleListeners = new HashSet<>();
//......
//全参数的构造函数,各种构造最终都走进这里
public FlutterEngine(
@NonNull Context context,
@Nullable FlutterLoader flutterLoader,
@NonNull FlutterJNI flutterJNI,
@NonNull PlatformViewsController platformViewsController,
@Nullable String[] dartVmArgs,
boolean automaticallyRegisterPlugins,
boolean waitForRestorationData) {
//......
//创建一个DartExecutor并将flutterJNI和安卓平台的assetManager实例传递进去。
this.dartExecutor = new DartExecutor(flutterJNI, assetManager);
this.dartExecutor.onAttachedToJNI();
//......
//各种channel实例化
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);
//......
//插件实例化。
this.localizationPlugin = new LocalizationPlugin(context, localizationChannel);
this.flutterJNI = flutterJNI;
if (flutterLoader == null) {
flutterLoader = FlutterInjector.instance().flutterLoader();
}
//......
// 引擎与四大组件的桥梁
this.pluginRegistry =
new FlutterEngineConnectionRegistry(context.getApplicationContext(), this, flutterLoader);
//默认就是自动注册plugins的,可以通过清单文件配置变更等。
if (automaticallyRegisterPlugins && flutterLoader.automaticallyRegisterPlugins()) {
registerPlugins();
}
}
//......
//注册flutter项目根目录下pubspec.yaml中依赖的所有flutter plugins。
//Flutter tool会生成一个GeneratedPluginRegistrant的类。
private void registerPlugins() {
try {
Class<?> generatedPluginRegistrant = Class.forName("io.flutter.plugins.GeneratedPluginRegistrant");
Method registrationMethod = generatedPluginRegistrant.getDeclaredMethod("registerWith", FlutterEngine.class);
registrationMethod.invoke(null, this);
} catch (Exception e) {
Log.w(TAG, "Tried to automatically register plugins with FlutterEngine ("
+ this + ") but could not find and invoke the GeneratedPluginRegistrant.");
}
}
//......省略一堆属性成员的get方法
}
总结下Flutter主要作用:
到此FlutterEngine基本创建完成,内部细节不做详解。下面再来分析下createFlutterView
createFlutterView走到了FlutterActivityAndFragmentDelegate
的onCreateView方法
@NonNull
View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.v(TAG, "Creating FlutterView.");
ensureAlive();
if (host.getRenderMode() == RenderMode.surface) {
FlutterSurfaceView flutterSurfaceView =
new FlutterSurfaceView(
host.getActivity(), host.getTransparencyMode() == TransparencyMode.transparent);
// 允许自定义flutterSurfaceView
host.onFlutterSurfaceViewCreated(flutterSurfaceView);
// 创建拥有 FlutterSurfaceView 的 FlutterView。
flutterView = new FlutterView(host.getActivity(), flutterSurfaceView);
} else {
FlutterTextureView flutterTextureView = new FlutterTextureView(host.getActivity());
// 允许自定义flutterTextureView
host.onFlutterTextureViewCreated(flutterTextureView);
// 创建拥有 FlutterTextureView 的 FlutterView。
flutterView = new FlutterView(host.getActivity(), flutterTextureView);
}
// 添加侦听器以在 Flutter 呈现其第一帧时收到通知。
flutterView.addOnFirstFrameRenderedListener(flutterUiDisplayListener);
flutterSplashView = new FlutterSplashView(host.getContext());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
flutterSplashView.setId(View.generateViewId());
} else {
flutterSplashView.setId(486947586);
}
flutterSplashView.displayFlutterViewWithSplash(flutterView, host.provideSplashScreen());
Log.v(TAG, "Attaching FlutterEngine to FlutterView.");
flutterView.attachToFlutterEngine(flutterEngine);
return flutterSplashView;
}
该方法主要完成四个任务:
我们在简单看下FlutterView,FlutterView是一个Android 原生的控件,继承自FrameLayout,它之所以显示的是Flutter UI,完全是依赖于FlutterSurfaceView和FlutterTextureView,而FlutterSurfaceView和FlutterTextureView这两个View的绘制内容又是来自于FlutterEngine提供。
FlutterView源码分析,我们后面再来单独讲…
讲到这里,我们基本上了解了Flutter启动的大致流程。其实无论是FlutterActivity还是FlutterFragment都是通过代理类FlutterActivityAndFragmentDelegate来封装调用Flutter的各种行为。
下文我们在一起看看FlutterView是如何工作,Flutter UI是如何显示到原生界面上的。。。。