Flutter android emebed 初始化过程
Flutter 在android 平台的启动通过 FlutterActivity 实现。新建一个Flutter App 工程后,查看 MainActivity 很简单, 直接继承FlutterActivity。Flutter 的启动通过FlutterActivity 实现
public class MainActivity extends FlutterActivity {
}
FlutterActivity 启动flutter 根据Activity 的声明周期分为三大步,五小步。
一 Activity.onCreate
1.1 生成FlutterActivityAndFragmentDelegate
delegate = new FlutterActivityAndFragmentDelegate(this);
1.2 delegate onAttach 到FlutterActivity
delegate.onAttach(this);
在delegate.onAttach(this) 中分别调用
-
System.loadLibrary("flutter"); 加载flutter.so
-
// Perform one time initialization of the Dart VM and Flutter engine private static native void nativeInit( @NonNull Context context, @NonNull String[] args, @Nullable String bundlePath, @NonNull String appStoragePath, @NonNull String engineCachesPath, long initTimeMillis);
-
// Attaches this {@code FlutterJNI} instance to Flutter's native engine, which allows // for communication between Android code and Flutter's platform agnostic engine. private native long nativeAttach(@NonNull FlutterJNI flutterJNI);
1.3 createFlutterView
通过delegate 生成FlutterView
private View createFlutterView() {
return delegate.onCreateView(
/* inflater=*/ null,
/* container=*/ null,
/* savedInstanceState=*/ null,
/*flutterViewId=*/ FLUTTER_VIEW_ID,
/*shouldDelayFirstAndroidViewDraw=*/ getRenderMode() == RenderMode.surface);
}
在这一阶段主要是将java 层的SurfaceView或者TextureView 设置到native 层. 先生成一个FlutterView, 然后在 FlutterView 中嵌套 SurfaceView或者TextureView 。FlutterView 负责接收触摸事件,SurfaceView或者TextureView 负责渲染显示。
调用jni函数
private native void nativeSurfaceCreated(long nativeShellHolderId, @NonNull Surface surface);
二 Activity.onStart
protected void onStart() {
super.onStart();
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START);
if (stillAttachedForEvent("onStart")) {
delegate.onStart();
}
}
onstart 中也是通过 delegate 启动。
2.1 doInitialFlutterViewRun 运行flutter 代码
delegate 中调用doInitialFlutterViewRun 运行flutter 代码
private void doInitialFlutterViewRun() {
...
// Configure the Dart entrypoint and execute it.
DartExecutor.DartEntrypoint entrypoint =
libraryUri == null
? new DartExecutor.DartEntrypoint(
appBundlePathOverride, host.getDartEntrypointFunctionName())
: new DartExecutor.DartEntrypoint(
appBundlePathOverride, libraryUri, host.getDartEntrypointFunctionName());
flutterEngine.getDartExecutor().executeDartEntrypoint(entrypoint, host.getDartEntrypointArgs());
}
Jin 函数
private native void nativeRunBundleAndSnapshotFromLibrary(
long nativeShellHolderId,
@NonNull String bundlePath,
@Nullable String entrypointFunctionName,
@Nullable String pathToEntrypointFunction,
@NonNull AssetManager manager,
@Nullable List<String> entrypointArgs);
三 FlutterView onTouchEvent
FlutterView onToucheEvent 传递触摸事件到flutter
public boolean onTouchEvent(@NonNull MotionEvent event) {
if (!isAttachedToFlutterEngine()) {
return super.onTouchEvent(event);
}
// TODO(abarth): This version check might not be effective in some
// versions of Android that statically compile code and will be upset
// at the lack of |requestUnbufferedDispatch|. Instead, we should factor
// version-dependent code into separate classes for each supported
// version and dispatch dynamically.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
requestUnbufferedDispatch(event);
}
return androidTouchProcessor.onTouchEvent(event);
}
3.1AndroidTouchProcessor 传递触摸事件到flutter
AndroidTouchProcessor#
public boolean onTouchEvent(@NonNull MotionEvent event, @NonNull Matrix transformMatrix) {
// Send the packet to Flutter.
renderer.dispatchPointerDataPacket(packet, packet.position());
return true;
}
FlutterRenderer#
public void dispatchPointerDataPacket(@NonNull ByteBuffer buffer, int position) {
flutterJNI.dispatchPointerDataPacket(buffer, position);
}
FlutterJNI#
public void dispatchPointerDataPacket(@NonNull ByteBuffer buffer, int position) {
ensureRunningOnMainThread();
ensureAttachedToNative();
nativeDispatchPointerDataPacket(nativeShellHolderId, buffer, position);
}
四 总结
调用的native 函数依次是:
-
System.loadLibrary(“flutter”); 加载flutter.so
-
private static native void nativeInit(
@NonNull Context context,
@NonNull String[] args,
@Nullable String bundlePath,
@NonNull String appStoragePath,
@NonNull String engineCachesPath,
long initTimeMillis); 启动DartVm和初始化flutter 环境 -
private native long nativeAttach(@NonNull FlutterJNI flutterJNI); 建立 flutter 和 android 的通信
-
private native void nativeRunBundleAndSnapshotFromLibrary(
long nativeShellHolderId,
@NonNull String bundlePath,
@Nullable String entrypointFunctionName,
@Nullable String pathToEntrypointFunction,
@NonNull AssetManager manager,
@Nullable List entrypointArgs); 运行flutter 代码 -
private native void nativeDispatchPointerDataPacket(
long nativeShellHolderId, @NonNull ByteBuffer buffer, int position); 接受触摸事件