首先手動創建一個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介面方法命名都比較簡單直觀,這里不做詳細解釋,
再來看onCreate方法
@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();
}
這里我們重點關注兩步
- onAttach 內部創建初始化引擎
- createFlutterView() 創建FlutterView顯示到Activity上
下面著重一步一步來分析
onAttach
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);
}
setupFlutterEngine()
@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的理解:
- 是一個獨立的Flutter執行環境
- FlutterEngine 是一個容器,通過它可以在 Android 應用程式中運行 Dart 代碼,
- FlutterEngine 中的 Dart 代碼可以在后臺執行,也可以使用附帶的 FlutterRenderer 和 Dart 代碼將 Dart 端 UI 效果渲染到螢屏上,渲染可以開始和停止,從而允許 FlutterEngine 從 UI 互動轉移到僅進行資料處理,然后又回傳到 UI 互動的能力,
- 可能同時存在多個FlutterEngine執行Dart代碼,并且在單個Android應用程式中繪制UI,為了更好的記憶體性能特性,通過FlutterEngineGroup構造多個FlutterEngine,而不是直接通過FlutterEngine的建構式,
- 使用 FlutterEngine 執行 Dart 或 Flutter 代碼需要先通過 FlutterEngine 獲取 DartExecutor 參考,然后呼叫 DartExecutor 的executeDartEntrypoint(DartExecutor.DartEntrypoint)執行 Dart 代碼即可,同一個 FlutterEngine 實體中獲取的 DartExecutor 的executeDartEntrypoint(DartExecutor.DartEntrypoint)方法只能被呼叫一次,
- 要開始將 Flutter 內容渲染到螢屏上,請使用 getRenderer() 獲取 FlutterRenderer,然后附加一個 RenderSurface, 考慮使用 FlutterView 作為 RenderSurface,
- App 每個行程中創建第一個 FlutterEngine 實體的時候會加載 Flutter 引擎的原生庫并啟動 Dart VM(VM 存活生命周期跟隨行程),隨后同行程中其他的 FlutterEngines 將在同一個 VM 實體上運行,但在運行 DartExecutor 時將擁有自己的 Dart Isolate,每個 Isolate 都是一個獨立的 Dart 環境,除非通過 Isolate 埠,否則無法相互通信,
- App 每個行程中創建第一個 FlutterEngine 實體的時候會加載 Flutter 引擎的原生庫并啟動 Dart VM(VM 存活生命周期跟隨行程),隨后同行程中其他的 FlutterEngine 將在同一個 VM 實體上運行,但在運行 DartExecutor 時將擁有自己的 Dart Isolate,每個 Isolate 都是一個獨立的 Dart 環境,除非通過 Isolate 埠,否則無法相互通信,
最終整理對于一個多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主要作用:
- FlutterEngineConnectionRegistry:創建組件與四大引擎生命周期的橋梁,方便插件根據各個組件的生命周期處理
- registerPlugins:通過反射注冊自定義插件
- 各種Channel的初始化,建立引擎與平臺系統之間的橋梁
- DartExecutor:Dart執行環境創建,onAttachedToJNI之后,DartExecutor將開始處理與Dart背景關系之間的雙向通行,BinaryMessenger(向Dart發送訊息),PlatformMessageHandler,它接受來自Dart的訊息
- FlutterRenderer:渲染環境的創建
到此FlutterEngine基本創建完成,內部細節不做詳解,下面再來分析下createFlutterView
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;
}
該方法主要完成四個任務:
- 在 View 層次結構中創建一個新的 FlutterView
- 添加一個 FlutterUiDisplayListener
- 將 FlutterEngine 附加到新的 FlutterView
- flutterSplashView(主要作用是在 FlutterView render 渲染出來之前顯示一個SplashScreen),類似于過度圖
我們在簡單看下FlutterView,FlutterView是一個Android 原生的控制元件,繼承自FrameLayout,它之所以顯示的是Flutter UI,完全是依賴于FlutterSurfaceView和FlutterTextureView,而FlutterSurfaceView和FlutterTextureView這兩個View的繪制內容又是來自于FlutterEngine提供,
FlutterView原始碼分析,我們后面再來單獨講…
結尾
? 講到這里,我們基本上了解了Flutter啟動的大致流程,其實無論是FlutterActivity還是FlutterFragment都是通過代理類FlutterActivityAndFragmentDelegate來封裝呼叫Flutter的各種行為,
? 下文我們在一起看看FlutterView是如何作業,Flutter UI是如何顯示到原生界面上的,,,,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/328036.html
標籤:其他
上一篇:Android apk加固
