FlutterUI提供了Flutter for Android 的包,FlutterActivity
,FlutterFragmentActivity
,在平臺側初始化Flutter engine中的信息,上一篇中分析了Dart文件加載Android側的代碼Android加載Dart文件,第二步就是把Flutter相關的代碼繪製出來,經過兩個步驟初始化:platform_view_android_jni.cc
這個類做爲Android平臺的UI調用的JNI接口java
執行下述的三步操做,可以建立Flutter engine執行環境,傳遞Android端的SurfaceView給到Flutter engine,方便Flutter engine繪製相關的UI界面,執行完成上述步驟,Android側的SurfaceView已經注入到flutter引擎中,後續的文件見控制上面兩個步驟在flutter引擎中是如何工做。android
io.flutter.embedding.engine.FlutterJNI
engine/src/flutter/shell/platform/android/platform_view_android_jni.cc
,初始化flutter engine 運行環境Platform,GPU,IO,UI,MessageLoop,初始化DartVM,加載第三方庫,skia,ICU等,//engine/src/flutter/common/settings.cc
刪除engine/src/flutter/shell/platform/android/android_shell_holder.cc
清理運行環境 shell
使用代理類來處理相關的事件,Flutter是一個UI庫app
public final class FlutterActivityDelegate implements FlutterActivityEvents, Provider, PluginRegistry {
public void onCreate(Bundle savedInstanceState) {
<!-- 判斷平臺特性,處理相關window邏輯 -->
if (VERSION.SDK_INT >= 21) {
Window window = this.activity.getWindow();
window.addFlags(-2147483648);
window.setStatusBarColor(1073741824);
window.getDecorView().setSystemUiVisibility(1280);
}
<!-- 獲取intent參數 -->
String[] args = getArgsFromIntent(this.activity.getIntent());
<!-- 所有Flutter相關的文件初始化完成 -->
FlutterMain.ensureInitializationComplete(this.activity.getApplicationContext(), args);
this.flutterView = this.viewFactory.createFlutterView(this.activity);
if (this.flutterView == null) {
<!-- FlutterNativeView主要用於FlutterView操做JIN的方法邏輯進行封裝 -->
FlutterNativeView nativeView = this.viewFactory.createFlutterNativeView();
this.flutterView = new FlutterView(this.activity, (AttributeSet)null, nativeView);
this.flutterView.setLayoutParams(matchParent);
<!-- 添加SurfaceView到Activity窗口中 -->
this.activity.setContentView(this.flutterView);
<!-- 插件Flutter的啓動界面 -->
this.launchView = this.createLaunchView();
if (this.launchView != null) {
this.addLaunchView();
}
}
if (!this.loadIntent(this.activity.getIntent())) {
String appBundlePath = FlutterMain.findAppBundlePath(this.activity.getApplicationContext());
if (appBundlePath != null) {
this.runBundle(appBundlePath);
}
}
}
複製代碼
1.初始化DartExecutor執行相關的邏輯 2.負責處理FlutterUI相關的內容,建立SurfaceView提供給DartVM渲染FlutterUI代碼 3.註冊常規的Platform事件ide
public FlutterView(Context context, AttributeSet attrs, FlutterNativeView nativeView) {
//FlutterNativeView FlutterUI與JNI傳遞信息的類,確保不爲空
if (nativeView == null) {
this.mNativeView = new FlutterNativeView(activity.getApplicationContext());
} else {
this.mNativeView = nativeView;
}
this.dartExecutor = new DartExecutor(this.mNativeView.getFlutterJNI());
<!-- 判斷是否開啓軟件渲染 engine/src/flutter/common/settings.cc -->
this.mIsSoftwareRenderingEnabled = FlutterJNI.nativeGetIsSoftwareRenderingEnabled();
this.mAnimationScaleObserver = new FlutterView.AnimationScaleObserver(new Handler());
this.mMetrics = new FlutterView.ViewportMetrics();
<!-- mSurfaceCallback回調方法 -->
this.mSurfaceCallback = new Callback() {
public void surfaceCreated(SurfaceHolder holder) {
FlutterView.this.assertAttached();
FlutterView.this.mNativeView.getFlutterJNI().onSurfaceCreated(holder.getSurface());
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
FlutterView.this.assertAttached();
FlutterView.this.mNativeView.getFlutterJNI().onSurfaceChanged(width, height);
}
public void surfaceDestroyed(SurfaceHolder holder) {
FlutterView.this.assertAttached();
FlutterView.this.mNativeView.getFlutterJNI().onSurfaceDestroyed();
}
};
<!-- 使用平臺通道和Flutter engine進行通訊 -->
this.navigationChannel = new NavigationChannel(this.dartExecutor);
this.keyEventChannel = new KeyEventChannel(this.dartExecutor);
this.lifecycleChannel = new LifecycleChannel(this.dartExecutor);
this.systemChannel = new SystemChannel(this.dartExecutor);
this.settingsChannel = new SettingsChannel(this.dartExecutor);
this.mFlutterLocalizationChannel = new MethodChannel(this, "flutter/localization", JSONMethodCodec.INSTANCE);
PlatformPlugin platformPlugin = new PlatformPlugin(activity);
MethodChannel flutterPlatformChannel = new MethodChannel(this, "flutter/platform", JSONMethodCodec.INSTANCE);
flutterPlatformChannel.setMethodCallHandler(platformPlugin);
this.addActivityLifecycleListener(platformPlugin);
this.mImm = (InputMethodManager)this.getContext().getSystemService("input_method");
this.mTextInputPlugin = new TextInputPlugin(this);
this.androidKeyProcessor = new AndroidKeyProcessor(this.keyEventChannel);
this.setLocales(this.getResources().getConfiguration());
this.sendUserPlatformSettingsToDart();
}
複製代碼
構造函數中調用attach調用FlutterJNI
中的nativeAttach調用JNI方法進入platform_view_android_jni.cc
初始化AndroidShellHolder
,FlutterNativeView主要處理UI和JNI層的邏輯,FlutterJNI
,直接與JNI通訊的邏輯,調用Attach對Flutter engine運行環境進行調用,初始化環境函數
public FlutterNativeView(Context context, boolean isBackgroundView) {
this.mNextReplyId = 1;
this.mPendingReplies = new HashMap();
this.mContext = context;
this.mPluginRegistry = new FlutterPluginRegistry(this, context);
this.mFlutterJNI = new FlutterJNI();
this.mFlutterJNI.setRenderSurface(new FlutterNativeView.RenderSurfaceImpl());
this.mFlutterJNI.setPlatformMessageHandler(new FlutterNativeView.PlatformMessageHandlerImpl());
this.mFlutterJNI.addEngineLifecycleListener(new FlutterNativeView.EngineLifecycleListenerImpl());
<!-- 主要功能是初始化AndroidShellHolder的管理類 -->
this.attach(this, isBackgroundView);
this.assertAttached();
this.mMessageHandlers = new HashMap();
}
複製代碼
engine/src/flutter/shell/platform/android/platform_view_android_jni.cc
,flutterView在初始化時完成android_shell_holder
的初始化,方法註冊進入JNI,主要的做用是對AndroidShellHolder
進行初始oop
static jlong AttachJNI(JNIEnv* env, jclass clazz, jobject flutterJNI, jboolean is_background_view) {
fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterJNI);
// 初始化shellholder
auto shell_holder = std::make_unique<AndroidShellHolder>(
FlutterMain::Get().GetSettings(), java_object, is_background_view);
if (shell_holder->IsValid()) {
return reinterpret_cast<jlong>(shell_holder.release());
} else {
return 0;
}
}
複製代碼
!!! WARNING "從這裏開始就是初始化相關的環境,包括MessageLoop,Platform,GPU,UI,IO線程進行建立,加載第三方庫,建立DartVM提供一個能夠運行Dart代碼的環境。後續文件回調Flutter Engine進行初始化進行擴展"post
本地SurfaceView初始化完成以後提供給FlutterUI繪製的接口,Flutter使用skia引擎繪製2D圖像,把Platform相關的View注入到Flutter engine中提供能夠繪製的UI給skia進行圖像繪製性能
this.mSurfaceCallback = new Callback() {
public void surfaceCreated(SurfaceHolder holder) {
FlutterView.this.assertAttached();
FlutterView.this.mNativeView.getFlutterJNI().onSurfaceCreated(holder.getSurface());
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
FlutterView.this.assertAttached();
FlutterView.this.mNativeView.getFlutterJNI().onSurfaceChanged(width, height);
}
public void surfaceDestroyed(SurfaceHolder holder) {
FlutterView.this.assertAttached();
FlutterView.this.mNativeView.getFlutterJNI().onSurfaceDestroyed();
}
};
複製代碼
engine/src/flutter/shell/platform/android/platform_view_android_jni.cc
,android本地Surface建立時調用android本地窗口進行繪製ANativeWindow_fromSurface,使用AnativeWindow本地接口提供給本地接口使用ui
static void SurfaceCreated(JNIEnv* env, jobject jcaller, jlong shell_holder, jobject jsurface) {
// Note: This frame ensures that any local references used by
// ANativeWindow_fromSurface are released immediately. This is needed as a
// workaround for https://code.google.com/p/android/issues/detail?id=68174
fml::jni::ScopedJavaLocalFrame scoped_local_reference_frame(env);
auto window = fml::MakeRefCounted<AndroidNativeWindow>(
ANativeWindow_fromSurface(env, jsurface));
ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyCreated(std::move(window));
}
static void SurfaceChanged(JNIEnv* env, jobject jcaller, jlong shell_holder, jint width, jint height) {
ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyChanged(
SkISize::Make(width, height));
}
static void SurfaceDestroyed(JNIEnv* env, jobject jcaller, jlong shell_holder) {
ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyDestroyed();
}
複製代碼
至此,Android端的View的初始化就已經完成,等待DartVM執行相關的代碼來完成相關的繪製工做,Android端的 View 的初始化比較簡單,後續再對JNI層的代碼進行分析。