Flutter源码分析之初始化篇一(android)
前言
回想在公司工作拿到的第一个项目是一个flash游戏项目,在那个时候flash游戏非常流行,还没有被html5取代的迹象。游戏程序架构采用的是后端mfc+前端flash框架,整个项目代码20万行,就我自己一个人开发。公司的要求是能修改、增加游戏的功能。当时我虽然有一点mfc的基础,但是游戏没有接触过、flash的actionscript3更是一窍不通。那怎么办呢?学呗。于是经过一两个月的各种画uml图、流程图、写伪代码等等一系列的理解学习,发现不但理解了后端、前端的工作原理,甚至可以开始撸框架了。那个时候成天跟人吹牛,现在想起来还是觉得十分的有趣。一个看似庞大的体系从一窍不通到彻底掌握,这个过程只要经历一遍,之后就觉得没有什么问题是解决不了的。
flutter在实现上破天荒的没有采用目前的各种成熟视图体系,而是采用了自己构建一套视图体系,用gpu加速,所以性能高、界面流畅。对此,表示十分的感兴趣。那么要彻底的挖掘一个框架的本质,就只有研究源码这么一条道路。从今天起,预计花一到两个月的时间来分析flutter的源码,在这里给大家分享下研究的过程。
这一系列的文章应该会非常长,研究源码需要耐心,不是么。
文章结构
笔者认为这样
- 分析代码
- 提出这段代码问题,应该在后续的分析中解决
- 解决问题,分析前面的问题哪些是解决的
- 总结代码
- 在阶段性分析后给出图
flutter源码分析之FlutterActivity
实现接口分析
/// activity实现了三个接口 public class FlutterActivity extends Activity implements Provider, PluginRegistry, ViewFactory { /// 视图提供类,一个方法getFlutterView public interface Provider { FlutterView getFlutterView(); } /// 插件注册 public interface PluginRegistry { /// 注册一个插件 PluginRegistry.Registrar registrarFor(String var1); /// 是否有这个插件 boolean hasPlugin(String var1); /// 插件发布值 <T> T valuePublishedByPlugin(String var1); /// 下面开始为插件生命周期回调 public interface PluginRegistrantCallback { void registerWith(PluginRegistry var1); } /// 显然是视图销毁的回调 public interface ViewDestroyListener { boolean onViewDestroy(FlutterNativeView var1); } //// 不知道干啥,先留着 public interface UserLeaveHintListener { void onUserLeaveHint(); } //// activity生命周期回调之onNewIntent public interface NewIntentListener { boolean onNewIntent(Intent var1); } //// activity生命周期回调之onActivityResult public interface ActivityResultListener { boolean onActivityResult(int var1, int var2, Intent var3); } //// activity生命周期回调之onRequestPermissionsResult public interface RequestPermissionsResultListener { boolean onRequestPermissionsResult(int var1, String[] var2, int[] var3); } /// 插件的注册者,相当于插件的宿主。 public interface Registrar { Activity activity(); Context context(); Context activeContext(); /// 这个BinaryMessager还不知道干啥 BinaryMessenger messenger(); /// TextureRegistry不清楚 TextureRegistry textures(); /// 获取视图 FlutterView view(); /// 寻找资源 String lookupKeyForAsset(String var1); /// 寻找资源 String lookupKeyForAsset(String var1, String var2); /// 发布值,与上面的valuePublishedByPlugin对应 PluginRegistry.Registrar publish(Object var1); /// 增加生命周期回调 PluginRegistry.Registrar addRequestPermissionsResultListener(PluginRegistry.RequestPermissionsResultListener var1); /// 增加生命周期回调 PluginRegistry.Registrar addActivityResultListener(PluginRegistry.ActivityResultListener var1); PluginRegistry.Registrar addNewIntentListener(PluginRegistry.NewIntentListener var1); /// 增加生命周期回调 PluginRegistry.Registrar addUserLeaveHintListener(PluginRegistry.UserLeaveHintListener var1); /// 增加生命周期回调 PluginRegistry.Registrar addViewDestroyListener(PluginRegistry.ViewDestroyListener var1); } } /// 视图工厂 public interface ViewFactory { /// 创建flutterView FlutterView createFlutterView(Context var1); //// 创建nativeview FlutterNativeView createFlutterNativeView(); /// 暂时搞不清楚干啥的,先留着 boolean retainFlutterNativeView(); }
问题
- (1)FlutterNativeView和FlutterView有啥区别和联系
- (2)UserLeaveHintListener作用?
- (3)ViewFactory#retainFlutterNativeView作用?
- (4)BinaryMessenger作用
- (5)TextureRegistry作用
这些问题在之后的分析中应该能解决。
Activity的生命周期分析
构造函数
///创建FlutterActivityDelegate private final FlutterActivityDelegate delegate = new FlutterActivityDelegate(this, this); private final FlutterActivityEvents eventDelegate; private final Provider viewProvider; private final PluginRegistry pluginRegistry; public FlutterActivity() { /// FlutterActivityDelegate实现了这三个接口,并赋值给三个变量,这样调用起来更加清晰。 this.eventDelegate = this.delegate; this.viewProvider = this.delegate; this.pluginRegistry = this.delegate; }
onCreate、onResume、onStop、onDestory、onPause、onNewIntent、onStart、onActivityResult、onRequestPermissionResult
///这里都是由创建FlutterActivityDelegate代理执行,就不一一贴出来了 protected void onXXX() { super.onXXX(); this.eventDelegate.onXXX(); }
创建FlutterView
值得注意的是这里的三个回调,表示FlutterView是如何创建出来的。
public FlutterView getFlutterView() { /// 有关的函数,只有这个由FlutterActivityDelegate代理执行 return this.viewProvider.getFlutterView(); } public FlutterView createFlutterView(Context context) { return null; } public FlutterNativeView createFlutterNativeView() { return null; } public boolean retainFlutterNativeView() { return false; }
FlutterActivity总结
- FlutterActivity的生命周期和各个方法实际上由FlutterActivityDelegate代理执行。
- 从Activity的源码来看,已经清晰的看出FlutterActivity解决了生命周期的回调,插件管理,创建FlutterView以及相关的ui。
问题
- (6)FlutterView究竟如何创建的
- (7)retainFlutterNativeView有什么作用
flutter源码分析之FlutterActivityDelegate
还是onCreate
/// 启动参数解析 String[] args = getArgsFromIntent(this.activity.getIntent()); /// 等待并保证初始化完成 FlutterMain.ensureInitializationComplete(this.activity.getApplicationContext(), args); /// 创建flutterView,注意到上面默认的返回null this.flutterView = this.viewFactory.createFlutterView(this.activity); if (this.flutterView == null) { /// 默认走这里,createFlutterNativeView默认返回null FlutterNativeView nativeView = this.viewFactory.createFlutterNativeView(); //实际创建了FlutterView this.flutterView = new FlutterView(this.activity, (AttributeSet)null, nativeView); // 设置layout,并添加到当前activity,作为主视图 this.flutterView.setLayoutParams(matchParent); this.activity.setContentView(this.flutterView); //创建启动ui this.launchView = this.createLaunchView(); if (this.launchView != null) { //如果有创建启动ui成功,那么增加到当前activity上面 this.addLaunchView(); } }
看下FlutterMain.ensureInitializationComplete
public static void ensureInitializationComplete(Context applicationContext, String[] args) { // 保证ui线程运行 if (Looper.myLooper() != Looper.getMainLooper()) { throw new IllegalStateException("ensureInitializationComplete must be called on the main thread"); } else if (!sInitialized) { try { // 等待完成,这里有个疑问点,sResourceExtractor是什么时候创建的 sResourceExtractor.waitForCompletion(); // 继续解析参数 List<String> shellArgs = new ArrayList(); shellArgs.add("--icu-data-file-path=" + new File(PathUtils.getDataDirectory(applicationContext), "icudtl.dat")); if (args != null) { Collections.addAll(shellArgs, args); } if (sIsPrecompiledAsSharedLibrary) { shellArgs.add("--aot-shared-library-path=" + new File(PathUtils.getDataDirectory(applicationContext), sAotSharedLibraryPath)); } else { if (sIsPrecompiledAsBlobs) { shellArgs.add("--aot-snapshot-path=" + PathUtils.getDataDirectory(applicationContext)); } else { shellArgs.add("--cache-dir-path=" + PathUtils.getCacheDirectory(applicationContext)); shellArgs.add("--aot-snapshot-path=" + PathUtils.getDataDirectory(applicationContext) + "/" + sFlutterAssetsDir); } shellArgs.add("--vm-snapshot-data=" + sAotVmSnapshotData); shellArgs.add("--vm-snapshot-instr=" + sAotVmSnapshotInstr); shellArgs.add("--isolate-snapshot-data=" + sAotIsolateSnapshotData); shellArgs.add("--isolate-snapshot-instr=" + sAotIsolateSnapshotInstr); } if (sSettings.getLogTag() != null) { shellArgs.add("--log-tag=" + sSettings.getLogTag()); } // 查找bundle String appBundlePath = findAppBundlePath(applicationContext); // native初始化,参数为解析的所有启动参数和一个bundle的路径 nativeInit(applicationContext, (String[])shellArgs.toArray(new String[0]), appBundlePath); sInitialized = true; } catch (Exception var4) { Log.e("FlutterMain", "Flutter initialization failed.", var4); throw new RuntimeException(var4); } } }
///这里的nativeInit是jni调用,实际作用是? 这里我猜是初始化dart环境,并初始化加载bundle,类似初始化js环境,并加载jsbundle private static native void nativeInit(Context var0, String[] var1, String var2);
看下:
sResourceExtractor.waitForCompletion();
sResourceExtractor是啥时候创建的?那么这里全局搜索了一番,了解到到FlutterMain#startInitialization这个方法是在FlutterApplication中调用的,所以先看下Application。这里先提出疑问,之后解决。
问题
- (8)sResourceExtractor.waitForCompletion();在干什么?
- (9)new FlutterView(this.activity, (AttributeSet)null, nativeView);这里是否可以解释前面的问题(1)
- (10) nativeInit作用?bundle是什么,如何加载?
flutter源码分析之FlutterApplication
本来这个Application应该是第一个分析的,但是首先用户看到的flutter创建的example里面暴露的第一个类应该就是FlutterActivity。FlutterApplication是在AndroidManifest中定义的,所以笔者一开始没有注意到,这里插个队补上。
public class FlutterApplication extends Application { private Activity mCurrentActivity = null; public FlutterApplication() { } // 显然这里进行了全局初始化 @CallSuper public void onCreate() { super.onCreate(); FlutterMain.startInitialization(this); } public Activity getCurrentActivity() { return this.mCurrentActivity; } // 设置当前的Activity public void setCurrentActivity(Activity mCurrentActivity) { this.mCurrentActivity = mCurrentActivity; } }
FlutterMain.startInitialization
public static void startInitialization(Context applicationContext, FlutterMain.Settings settings) { 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); initAot(applicationContext); initResources(applicationContext); System.loadLibrary("flutter"); long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis; nativeRecordStartTimestamp(initTimeMillis); } }
Setting
这里的Setting非常简单,只是提供了日志的tag,那么这个logTag在哪里用?又是一个疑问。
public static class Settings { private String logTag; public Settings() { } public String getLogTag() { return this.logTag; } public void setLogTag(String tag) { this.logTag = tag; } }
initConfig
initConfig,这个函数主要用于初始化配置
private static void initConfig(Context applicationContext) { try { Bundle metadata = applicationContext.getPackageManager().getApplicationInfo(applicationContext.getPackageName(), 128).metaData; if (metadata != null) { sAotSharedLibraryPath = metadata.getString(PUBLIC_AOT_AOT_SHARED_LIBRARY_PATH, "app.so"); sAotVmSnapshotData = metadata.getString(PUBLIC_AOT_VM_SNAPSHOT_DATA_KEY, "vm_snapshot_data"); sAotVmSnapshotInstr = metadata.getString(PUBLIC_AOT_VM_SNAPSHOT_INSTR_KEY, "vm_snapshot_instr"); sAotIsolateSnapshotData = metadata.getString(PUBLIC_AOT_ISOLATE_SNAPSHOT_DATA_KEY, "isolate_snapshot_data"); sAotIsolateSnapshotInstr = metadata.getString(PUBLIC_AOT_ISOLATE_SNAPSHOT_INSTR_KEY, "isolate_snapshot_instr"); sFlx = metadata.getString(PUBLIC_FLX_KEY, "app.flx"); sSnapshotBlob = metadata.getString(PUBLIC_SNAPSHOT_BLOB_KEY, "snapshot_blob.bin"); sFlutterAssetsDir = metadata.getString(PUBLIC_FLUTTER_ASSETS_DIR_KEY, "flutter_assets"); } } catch (NameNotFoundException var2) { throw new RuntimeException(var2); } }
这里可以看到flutter的定制选项,可以在androd的meta里面定义
- sAotSharedLibraryPath
- sAotVmSnapshotData
- sAotVmSnapshotInstr
- sAotIsolateSnapshotData
- sAotIsolateSnapshotInstr
- sFlx
- sSnapshotBlob
- sFlutterAssetsDir
initAot
关于aot,这里有几篇博文介绍:
https://www.cnblogs.com/zengm...
https://www.cnblogs.com/tinyt...
AOT是一种静态编译技术,与JIT对应
private static void initAot(Context applicationContext) { // 列出所有的assets文件夹中的资源 Set<String> assets = listRootAssets(applicationContext); // sIsPrecompiledAsBlobs = assets.containsAll(Arrays.asList(sAotVmSnapshotData, sAotVmSnapshotInstr, sAotIsolateSnapshotData, sAotIsolateSnapshotInstr)); sIsPrecompiledAsSharedLibrary = assets.contains(sAotSharedLibraryPath); // 意思是两个不能同时存在? if (sIsPrecompiledAsBlobs && sIsPrecompiledAsSharedLibrary) { throw new RuntimeException("Found precompiled app as shared library and as Dart VM snapshots."); } }
initResources
private static void initResources(Context applicationContext) { // 开始清理资源 (new ResourceCleaner(applicationContext)).start(); // 创建sResourceExtractor sResourceExtractor = (new ResourceExtractor(applicationContext)).addResources(SKY_RESOURCES).addResource(fromFlutterAssets(sFlx)).addResource(fromFlutterAssets(sSnapshotBlob)).addResource(fromFlutterAssets(sAotVmSnapshotData)).addResource(fromFlutterAssets(sAotVmSnapshotInstr)).addResource(fromFlutterAssets(sAotIsolateSnapshotData)).addResource(fromFlutterAssets(sAotIsolateSnapshotInstr)).addResource(fromFlutterAssets("kernel_blob.bin")).addResource(fromFlutterAssets("platform.dill")); // 增加资源 if (sIsPrecompiledAsSharedLibrary) { sResourceExtractor.addResource(sAotSharedLibraryPath); } else { sResourceExtractor.addResource(sAotVmSnapshotData).addResource(sAotVmSnapshotInstr).addResource(sAotIsolateSnapshotData).addResource(sAotIsolateSnapshotInstr).addResource(sSnapshotBlob); } //开始 sResourceExtractor.start(); }
看下:
(new ResourceCleaner(applicationContext)).start(),作用是清理缓存
boolean result = name.startsWith(".org.chromium.Chromium."); return result; ... protected Void doInBackground(Void... unused) { File[] var2 = this.mFilesToDelete; int var3 = var2.length; for(int var4 = 0; var4 < var3; ++var4) { File file = var2[var4]; if (file.exists()) { this.deleteRecursively(file); } } }
看下:sResourceExtractor.start();
ResourceExtractor start() { assert this.mExtractTask == null; this.mExtractTask = new ResourceExtractor.ExtractTask(); this.mExtractTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Void[0]); return this; } ... private void extractResources() { File dataDir = new File(PathUtils.getDataDirectory(ResourceExtractor.this.mContext)); ... InputStream is = manager.open(asset); Throwable var9 = null; try { OutputStream os = new FileOutputStream(output); Throwable var11 = null; ... while((count = is.read(buffer, 0, 16384)) != -1) { os.write(buffer, 0, count); } ... } ... public final class PathUtils { ... public static String getDataDirectory(Context applicationContext) { return applicationContext.getDir("Lflutter", 0).getPath(); } ... }
这段代码是将指定的assert文件夹中的文件拷贝到应用程序目录中的flutter文件夹下,说明后续程序需要直接使用文件,而不是assert文件夹中的二进制。
native部分
System.loadLibrary("flutter"); nativeRecordStartTimestamp(initTimeMillis);
初始化native,并记录时间,native的部分,这篇文章先不予考虑,专门在一个专题里面写。
问题
这次光看代码比较难以理解,需要动态调试了
- (11)sIsPrecompiledAsBlobs && sIsPrecompiledAsSharedLibrary这两个参数具体代表什么含义,为什么不能同时存在?和flutter的hotload有关吗,和flutter是调试版本还是发布版本有关吗?
- (12)flutter中的so库具体有哪些,有什么作用?
解决问题
- (8)sResourceExtractor.waitForCompletion();在干什么?
这次显然已经解决了前面的问题(8), FlutterActivity在启动的时候,需要等待FlutterApplicaiton中的异步加载资源完毕
总结
FlutterApplication在onCreate的时候,初始化加载Flutter中的资源,含bundle、so库等重要启动资源,而在FlutterActivity的onCreate中,会等待FlutterApplication的这个过程完毕之后再进行下一步的初始化。
Flutter源码分析创建FlutterView
这里接着上面来分析FlutterView的创建过程:
public class FlutterView extends SurfaceView implements BinaryMessenger, TextureRegistry, AccessibilityStateChangeListener {
注意到FlutterView继承了SurfaceView,关于SurfaceView,可以参考几篇博文理解:
https://blog.csdn.net/android...
https://www.cnblogs.com/zhang...
SurfaceView使用的绘图线程不是ui线程,我们平时使用的摄像头、游戏之类的要求图形性能比较高的场景就靠它了。
看下构造函数:
this.nextTextureId = new AtomicLong(0L); ... @Override public TextureRegistry.SurfaceTextureEntry createSurfaceTexture() { final SurfaceTexture surfaceTexture = new SurfaceTexture(0); surfaceTexture.detachFromGLContext(); final SurfaceTextureRegistryEntry entry = new SurfaceTextureRegistryEntry(nextTextureId.getAndIncrement(), surfaceTexture); nativeRegisterTexture(mNativeView.get(), entry.id(), surfaceTexture); return entry; }
这里使用到了SurfaceTexture,并执行了nativeRegisterTexture,关于SurfaceTexture,找到这么几篇博文:
https://www.cnblogs.com/wytig...
https://blog.csdn.net/hejjunl...
https://blog.csdn.net/u010949...
https://blog.csdn.net/tq08g2z...
https://blog.csdn.net/OnafioO...
https://blog.csdn.net/u010949...
https://blog.csdn.net/u010949...
基本上全是csdn的老文章!
这个SurfactTexture具体作用?先放放。
接着往下看:
this.mIsSoftwareRenderingEnabled = nativeGetIsSoftwareRenderingEnabled();
关于android的软件渲染还是硬件渲染:
https://blog.csdn.net/wlwl007...
https://blog.csdn.net/luoshen...
http://www.sohu.com/a/1605251...
继续
this.mMetrics = new FlutterView.ViewportMetrics(); this.mMetrics.devicePixelRatio = context.getResources().getDisplayMetrics().density; ... private void updateViewportMetrics() { if (this.isAttached()) { nativeSetViewportMetrics(this.mNativeView.get(), this.mMetrics.devicePixelRatio, this.mMetrics.physicalWidth, this.mMetrics.physicalHeight, this.mMetrics.physicalPaddingTop, this.mMetrics.physicalPaddingRight, this.mMetrics.physicalPaddingBottom, this.mMetrics.physicalPaddingLeft, this.mMetrics.physicalViewInsetTop, this.mMetrics.physicalViewInsetRight, this.mMetrics.physicalViewInsetBottom, this.mMetrics.physicalViewInsetLeft); WindowManager wm = (WindowManager)this.getContext().getSystemService("window"); float fps = wm.getDefaultDisplay().getRefreshRate(); VsyncWaiter.refreshPeriodNanos = (long)(1.0E9D / (double)fps); } } ... protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) { this.mMetrics.physicalWidth = width; this.mMetrics.physicalHeight = height; this.updateViewportMetrics(); super.onSizeChanged(width, height, oldWidth, oldHeight); } public final WindowInsets onApplyWindowInsets(WindowInsets insets) { this.mMetrics.physicalPaddingTop = insets.getSystemWindowInsetTop(); this.mMetrics.physicalPaddingRight = insets.getSystemWindowInsetRight(); this.mMetrics.physicalPaddingBottom = 0; this.mMetrics.physicalPaddingLeft = insets.getSystemWindowInsetLeft(); this.mMetrics.physicalViewInsetTop = 0; this.mMetrics.physicalViewInsetRight = 0; this.mMetrics.physicalViewInsetBottom = insets.getSystemWindowInsetBottom(); this.mMetrics.physicalViewInsetLeft = 0; this.updateViewportMetrics(); return super.onApplyWindowInsets(insets); } protected boolean fitSystemWindows(Rect insets) { if (VERSION.SDK_INT <= 19) { this.mMetrics.physicalPaddingTop = insets.top; this.mMetrics.physicalPaddingRight = insets.right; this.mMetrics.physicalPaddingBottom = 0; this.mMetrics.physicalPaddingLeft = insets.left; this.mMetrics.physicalViewInsetTop = 0; this.mMetrics.physicalViewInsetRight = 0; this.mMetrics.physicalViewInsetBottom = insets.bottom; this.mMetrics.physicalViewInsetLeft = 0; this.updateViewportMetrics(); return true; } else { return super.fitSystemWindows(insets); } } private boolean isAttached() { return this.mNativeView != null && this.mNativeView.isAttached(); }
这里又涉及到几个概念,基本都不怎么常用:
WindowInsets,onApplyWindowInsets:
https://blog.csdn.net/me_touc...
fitSystemWindows:
https://blog.csdn.net/ys40897...
static final class ViewportMetrics { float devicePixelRatio = 1.0F; int physicalWidth = 0; int physicalHeight = 0; int physicalPaddingTop = 0; int physicalPaddingRight = 0; int physicalPaddingBottom = 0; int physicalPaddingLeft = 0; int physicalViewInsetTop = 0; int physicalViewInsetRight = 0; int physicalViewInsetBottom = 0; int physicalViewInsetLeft = 0; ViewportMetrics() { } }
这段代码的意思显然是适配窗口大小的变化,并在恰当的时候更新mMetrics,并设置到native中
private static native void nativeSetViewportMetrics(long nativePlatformViewAndroid, float devicePixelRatio, int physicalWidth, int physicalHeight, int physicalPaddingTop, int physicalPaddingRight, int physicalPaddingBottom, int physicalPaddingLeft, int physicalViewInsetTop, int physicalViewInsetRight, int physicalViewInsetBottom, int physicalViewInsetLeft);
继续:
Activity activity = (Activity)this.getContext(); if (nativeView == null) { this.mNativeView = new FlutterNativeView(activity.getApplicationContext()); } else { this.mNativeView = nativeView; }
NativeView是什么?
public class FlutterNativeView implements BinaryMessenger { ... public FlutterNativeView(Context context) { this.mContext = context; // 插件管理 this.mPluginRegistry = new FlutterPluginRegistry(this, context); this.attach(this); this.assertAttached(); // 消息管理 this.mMessageHandlers = new HashMap(); } ... //涉及到和native打交道 private static native long nativeAttach(FlutterNativeView var0); private static native void nativeDestroy(long var0); private static native void nativeDetach(long var0); private static native void nativeRunBundleAndSnapshot(long var0, String var2, String var3, String var4, boolean var5, AssetManager var6); private static native void nativeRunBundleAndSource(long var0, String var2, String var3, String var4); private static native void nativeSetAssetBundlePathOnUI(long var0, String var2); private static native String nativeGetObservatoryUri(); private static native void nativeDispatchEmptyPlatformMessage(long var0, String var2, int var3); private static native void nativeDispatchPlatformMessage(long var0, String var2, ByteBuffer var3, int var4, int var5); private static native void nativeInvokePlatformMessageEmptyResponseCallback(long var0, int var2); private static native void nativeInvokePlatformMessageResponseCallback(long var0, int var2, ByteBuffer var3, int var4); }
NativeView显然是一个插件、消息的管理类,并与native打交道,那么和FlutterView的关系,显然一个负责展示,一个负责交互。这里解决了问题(1)
再往下看
this.mSurfaceCallback = new Callback() { public void surfaceCreated(SurfaceHolder holder) { FlutterView.this.assertAttached(); FlutterView.nativeSurfaceCreated(FlutterView.this.mNativeView.get(), holder.getSurface(), color); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { FlutterView.this.assertAttached(); FlutterView.nativeSurfaceChanged(FlutterView.this.mNativeView.get(), width, height); } public void surfaceDestroyed(SurfaceHolder holder) { FlutterView.this.assertAttached(); FlutterView.nativeSurfaceDestroyed(FlutterView.this.mNativeView.get()); } }; this.getHolder().addCallback(this.mSurfaceCallback);
这里监听了SurfaceView的生命周期,并调用native
this.mAccessibilityManager = (AccessibilityManager)this.getContext().getSystemService("accessibility"); this.mActivityLifecycleListeners = new ArrayList(); this.mFirstFrameListeners = new ArrayList(); this.mFlutterLocalizationChannel = new MethodChannel(this, "flutter/localization", JSONMethodCodec.INSTANCE); this.mFlutterNavigationChannel = new MethodChannel(this, "flutter/navigation", JSONMethodCodec.INSTANCE); this.mFlutterKeyEventChannel = new BasicMessageChannel(this, "flutter/keyevent", JSONMessageCodec.INSTANCE); this.mFlutterLifecycleChannel = new BasicMessageChannel(this, "flutter/lifecycle", StringCodec.INSTANCE); this.mFlutterSystemChannel = new BasicMessageChannel(this, "flutter/system", JSONMessageCodec.INSTANCE); this.mFlutterSettingsChannel = new BasicMessageChannel(this, "flutter/settings", JSONMessageCodec.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.setLocale(this.getResources().getConfiguration().locale); this.setUserSettings();
这段代码注册了一些Flutter的自带插件,主要用于输入、生命周期、国际化等系统相关的插件,有时间再一个一个分析,先放放。
问题
- (13)native中的初始化流程?
- (14)这里并没有看到一行代码有和绘制图形有关,那么在哪里调用?是否都是在native中调用,怎么调用的?
解决问题
- (1)FlutterNativeView和FlutterView有啥区别和联系
本篇总结
全部问题:
- (1)
FlutterNativeView和FlutterView有啥区别和联系 - (2)UserLeaveHintListener作用?
- (3)ViewFactory#retainFlutterNativeView作用?
- (4)BinaryMessenger作用
- (5)TextureRegistry作用
- (6)FlutterView究竟如何创建的
- (7)retainFlutterNativeView有什么作用
- (8)
sResourceExtractor.waitForCompletion();在干什么? - (9)
new FlutterView(this.activity, (AttributeSet)null, nativeView);这里是否可以解释前面的问题(1) - (10) nativeInit作用?bundle是什么,如何加载?
- (11)sIsPrecompiledAsBlobs && sIsPrecompiledAsSharedLibrary这两个参数具体代表什么含义,为什么不能同时存在?和flutter的hotload有关吗,和flutter是调试版本还是发布版本有关吗?
- (12)flutter中的so库具体有哪些,有什么作用?
- (13)native中的初始化流程?
- (14)这里并没有看到一行代码有和绘制图形有关,那么在哪里调用?是否都是在native中调用,怎么调用的?
大部分问题在这里都解释不了,这里先用一张图表示一下启动流程:
如有疑问,请加qq群854192563讨论