前言
回想在公司工作拿到的第一个项目是一个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讨论
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。