Flutter UI容器 承载Flutter的Android容器 Flutter容器包含有FlutterActivity和FlutterFragmentActivity。他们分别实现了Provider
, PluginRegistry
, ViewFactory
,二者的方法主要通过FlutterActivityDelegate
代理出去
FlutterActivityDelegate FlutterActivityEvents Provider PluginRegistry FlutterActivity Activity ViewFactory FlutterFragmentActivity FragmentActivity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class FlutterActivity extends Activity implements Provider , PluginRegistry, ViewFactory{ private final FlutterActivityDelegate delegate = new FlutterActivityDelegate (this , this ); private final FlutterActivityEvents eventDelegate; private final Provider viewProvider; private final PluginRegistry pluginRegistry; public FlutterActivity () { this .eventDelegate = this .delegate; this .viewProvider = this .delegate; this .pluginRegistry = this .delegate; } } public class FlutterFragmentActivity extends FragmentActivity implements Provider , PluginRegistry, ViewFactory { private final FlutterActivityDelegate delegate = new FlutterActivityDelegate (this , this ); private final FlutterActivityEvents eventDelegate; private final Provider viewProvider; private final PluginRegistry pluginRegistry; public FlutterFragmentActivity () { this .eventDelegate = this .delegate; this .viewProvider = this .delegate; this .pluginRegistry = this .delegate; } }
其中 Provider
负责提供FlutterView
Provider FlutterView getFlutterView()
PluginRegistry
负责插件管理
PluginRegistry PluginRegistry.Registrar registrarFor(String var1); boolean hasPlugin(String var1); <T> T valuePublishedByPlugin(String var1);
ViewFactory
负责管理FlutterView和FlutterNative
ViewFactory FlutterView createFlutterView(Context var1); FlutterNativeView createFlutterNativeView(); boolean retainFlutterNativeView();
Flutter容器代理类 FlutterActivityDelegate 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public final class FlutterActivityDelegate implements FlutterActivityEvents , Provider, PluginRegistry { public void onCreate (Bundle savedInstanceState) { if (VERSION.SDK_INT >= 21 ) { Window window = this .activity.getWindow(); window.addFlags(-2147483648 ); window.setStatusBarColor(1073741824 ); window.getDecorView().setSystemUiVisibility(1280 ); } String[] args = getArgsFromIntent(this .activity.getIntent()); FlutterMain.ensureInitializationComplete(this .activity.getApplicationContext(), args); this .flutterView = this .viewFactory.createFlutterView(this .activity); if (this .flutterView == null ) { FlutterNativeView nativeView = this .viewFactory.createFlutterNativeView(); this .flutterView = new FlutterView (this .activity, (AttributeSet)null , nativeView); this .flutterView.setLayoutParams(matchParent); this .activity.setContentView(this .flutterView); this .launchView = this .createLaunchView(); if (this .launchView != null ) { this .addLaunchView(); } } if (!this .loadIntent(this .activity.getIntent())) { String appBundlePath = FlutterMain.findAppBundlePath(); if (appBundlePath != null ) { this .runBundle(appBundlePath); } } } }
FlutterView FlutterView 是Flutter在Native上实际的绘制视图。
FlutterView SurfaceView BinaryMessenger TextureRegistry
BinaryMessenger
是Flutter与Native同学的通道,后面会详细讲到TextureRegistry
用于管理SurfaceTexture
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 public class FlutterView extends SurfaceView implements BinaryMessenger , TextureRegistry { public FlutterView (Context context, AttributeSet attrs, FlutterNativeView nativeView) { if (nativeView == null ) { this .mNativeView = new FlutterNativeView (activity.getApplicationContext()); } else { this .mNativeView = nativeView; } this .dartExecutor = this .mNativeView.getDartExecutor(); this .flutterRenderer = new FlutterRenderer (this .mNativeView.getFlutterJNI()); this .mIsSoftwareRenderingEnabled = FlutterJNI.nativeGetIsSoftwareRenderingEnabled(); this .mMetrics = new FlutterView .ViewportMetrics(); this .mMetrics.devicePixelRatio = context.getResources().getDisplayMetrics().density; this .setFocusable(true ); this .setFocusableInTouchMode(true ); this .mNativeView.attachViewAndActivity(this , activity); 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(); } }; this .getHolder().addCallback(this .mSurfaceCallback); this .mActivityLifecycleListeners = new ArrayList (); this .mFirstFrameListeners = new ArrayList (); this .navigationChannel = new NavigationChannel (this .dartExecutor); this .keyEventChannel = new KeyEventChannel (this .dartExecutor); this .lifecycleChannel = new LifecycleChannel (this .dartExecutor); this .localizationChannel = new LocalizationChannel (this .dartExecutor); this .platformChannel = new PlatformChannel (this .dartExecutor); this .systemChannel = new SystemChannel (this .dartExecutor); this .settingsChannel = new SettingsChannel (this .dartExecutor); final PlatformPlugin platformPlugin = new PlatformPlugin (activity, this .platformChannel); this .addActivityLifecycleListener(new ActivityLifecycleListener () { public void onPostResume () { platformPlugin.updateSystemUiOverlays(); } }); this .mImm = (InputMethodManager)this .getContext().getSystemService("input_method" ); PlatformViewsController platformViewsController = this .mNativeView.getPluginRegistry().getPlatformViewsController(); this .mTextInputPlugin = new TextInputPlugin (this , this .dartExecutor, platformViewsController); this .androidKeyProcessor = new AndroidKeyProcessor (this .keyEventChannel, this .mTextInputPlugin); this .androidTouchProcessor = new AndroidTouchProcessor (this .flutterRenderer); this .mNativeView.getPluginRegistry().getPlatformViewsController().attachTextInputPlugin(this .mTextInputPlugin); this .sendLocalesToDart(this .getResources().getConfiguration()); this .sendUserPlatformSettingsToDart(); } }
在FlutterActivityDelegate
中我们知道,加载dart执行的是FlutterView
的runFromBundle
。
1 2 3 4 5 6 public void runFromBundle (FlutterRunArguments args) { this .assertAttached(); this .preRun(); this .mNativeView.runFromBundle(args); this .postRun(); }
实际上调用的是mNativeView.runFromBundle(args)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class FlutterNativeView implements BinaryMessenger { public void runFromBundle (FlutterRunArguments args) { if (args.entrypoint == null ) { throw new AssertionError ("An entrypoint must be specified" ); } else { this .assertAttached(); if (this .applicationIsRunning) { throw new AssertionError ("This Flutter engine instance is already running an application" ); } else { this .mFlutterJNI.runBundleAndSnapshotFromLibrary(args.bundlePath, args.entrypoint, args.libraryPath, this .mContext.getResources().getAssets()); this .applicationIsRunning = true ; } } } }
可以看到,最后调用的是mFlutterJNI。
FlutterNativeView与FlutterJNI 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class FlutterNativeView implements BinaryMessenger { public FlutterNativeView (@NonNull Context context, boolean isBackgroundView) { this .mContext = context; this .mPluginRegistry = new FlutterPluginRegistry (this , context); this .mFlutterJNI = new FlutterJNI (); this .mFlutterJNI.setRenderSurface(new FlutterNativeView .RenderSurfaceImpl()); this .dartExecutor = new DartExecutor (this .mFlutterJNI, context.getAssets()); this .mFlutterJNI.addEngineLifecycleListener(new FlutterNativeView .EngineLifecycleListenerImpl()); this .attach(this , isBackgroundView); this .assertAttached(); } public void runFromBundle (FlutterRunArguments args) { if (args.entrypoint == null ) { throw new AssertionError ("An entrypoint must be specified" ); } else { this .assertAttached(); if (this .applicationIsRunning) { throw new AssertionError ("This Flutter engine instance is already running an application" ); } else { this .mFlutterJNI.runBundleAndSnapshotFromLibrary(args.bundlePath, args.entrypoint, args.libraryPath, this .mContext.getResources().getAssets()); this .applicationIsRunning = true ; } } } }
小结 FlutterActivity FlutterActivityDelegate FlutterActivity 是主要承载页面, 具体的实现由FlutterActivityDelegate代理 FlutterActivityDelegate 创建FlutterView, 并加载Flutter bundle FlutterView FlutterView 继承于SurfaceView, 为实际渲染的native view FlutterView初始化时会设置UI相关的信息 以及内置的Channel,FlutterView与FlutterNativeView 相互绑定 FlutterNativeView FlutterNativeView继承于BinaryMessenger, 并持有FlutterJNI,而FlutterJNI是Android与 FlutterEngine交互的桥梁 FlutterJNI 大部分是jni的native方法,与Flutter Engine交互
Flutter Engine Flutter 初始化 在使用Flutter前需要初始化Flutter
1 FlutterMain.startInitialization(applicationContext);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class FlutterMain { public static void startInitialization (@NonNull Context applicationContext) { if (!isRunningInRobolectricTest) { startInitialization(applicationContext, new FlutterMain .Settings()); } } public static void startInitialization (@NonNull Context applicationContext, @NonNull FlutterMain.Settings settings) { if (!isRunningInRobolectricTest) { if (Looper.myLooper() != Looper.getMainLooper()) { throw new IllegalStateException ("startInitialization must be called on the main thread" ); } else if (sSettings == null ) { sSettings = settings; long initStartTimestampMillis = SystemClock.uptimeMillis(); initConfig(applicationContext); initResources(applicationContext); System.loadLibrary("flutter" ); VsyncWaiter.getInstance((WindowManager)applicationContext.getSystemService("window" )).init(); long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis; FlutterJNI.nativeRecordStartTimestamp(initTimeMillis); } } } }
android assets目录下flutter_assets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 assets └── flutter_assets ├── AssetManifest.json ├── FontManifest.json ├── LICENSE ├── fonts │ └── MaterialIcons-Regular.ttf ├── isolate_snapshot_data ├── kernel_blob.bin ├── packages │ └── cupertino_icons │ └── assets │ └── CupertinoIcons.ttf └── vm_snapshot_data
在FlutterActivityDelegate
中,onCreate
时,
1 2 3 4 5 public final class FlutterActivityDelegate { public void onCreate (Bundle savedInstanceState) { FlutterMain.ensureInitializationComplete(this .activity.getApplicationContext(), args); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 public class FlutterMain { public static void ensureInitializationComplete (@NonNull Context applicationContext, @Nullable String[] args) { if (!isRunningInRobolectricTest) { if (Looper.myLooper() != Looper.getMainLooper()) { throw new IllegalStateException ("ensureInitializationComplete must be called on the main thread" ); } else if (sSettings == null ) { throw new IllegalStateException ("ensureInitializationComplete must be called after startInitialization" ); } else if (!sInitialized) { try { if (sResourceExtractor != null ) { sResourceExtractor.waitForCompletion(); } List<String> shellArgs = new ArrayList (); shellArgs.add("--icu-symbol-prefix=_binary_icudtl_dat" ); ApplicationInfo applicationInfo = getApplicationInfo(applicationContext); shellArgs.add("--icu-native-lib-path=" + applicationInfo.nativeLibraryDir + File.separator + "libflutter.so" ); if (args != null ) { Collections.addAll(shellArgs, args); } String kernelPath = null ; String appStoragePath = PathUtils.getDataDirectory(applicationContext) + File.separator + sFlutterAssetsDir; kernelPath = appStoragePath + File.separator + "kernel_blob.bin" ; shellArgs.add("--snapshot-asset-path=" + appStoragePath); shellArgs.add("--vm-snapshot-data=" + sVmSnapshotData); shellArgs.add("--isolate-snapshot-data=" + sIsolateSnapshotData); shellArgs.add("--cache-dir-path=" + PathUtils.getCacheDirectory(applicationContext)); if (sSettings.getLogTag() != null ) { shellArgs.add("--log-tag=" + sSettings.getLogTag()); } appStoragePath = PathUtils.getFilesDir(applicationContext); String engineCachesPath = PathUtils.getCacheDirectory(applicationContext); FlutterJNI.nativeInit(applicationContext, (String[])shellArgs.toArray(new String [0 ]), kernelPath, appStoragePath, engineCachesPath); sInitialized = true ; } catch (Exception var7) { Log.e("FlutterMain" , "Flutter initialization failed." , var7); throw new RuntimeException (var7); } } } } }
可以看到,所有与Flutter Engine相关的操作都是用过FlutterJNI来交互的
小结 Flutter Engine初始化主要是加载flutter.so
,设置flutter_assets
,并通过FlutterJNI设置到Flutter Engine中。
关于FlutterJNI相关的内容,再后面关于Flutter Engine定制中会详细介绍到。