Flutter Android 端 FlutterInjector 及依赖流程源码分析
throw new IllegalStateException(“startInitialization must be called on the main thread”);
}
final Context appContext = applicationContext.getApplicationContext();
this.settings = settings;
initStartTimestampMillis = SystemClock.uptimeMillis();
//步骤11、通过ApplicationInfoLoader的load获取FlutterApplicationInfo信息。
//里面主要都是flutterAssetsDir、nativeLibraryDir、aotSharedLibraryName等信息,下一小节专门分析FlutterApplicationInfo。
flutterApplicationInfo = ApplicationInfoLoader.load(appContext);
//步骤12、平台VSYNC信号相关初始化设置,下面单独小节分析。
VsyncWaiter.getInstance((WindowManager) appContext.getSystemService(Context.WINDOW_SERVICE))
.init();
//步骤13、由于需要访问磁盘,异步调用执行初始化相关东西。
Callable initTask =
new Callable() {
@Override
public InitResult call() {
//步骤14、异步调用initResources得到ResourceExtractor。
ResourceExtractor resourceExtractor = initResources(appContext);
//步骤15、通过flutterJNI调用加载框架so,即libflutter.so
flutterJNI.loadLibrary();
//步骤16、异步之上再异步先尽可能快获取默认的font manager。
Executors.newSingleThreadExecutor()
.execute(
new Runnable() {
@Override
public void run() {
flutterJNI.prefetchDefaultFontManager();
}
});
//步骤17、等待ResourceExtractor异步任务结束。
if (resourceExtractor != null) {
resourceExtractor.waitForCompletion();
}
//步骤18、返回异步执行的结果结构。
return new InitResult(
PathUtils.getFilesDir(appContext),
PathUtils.getCacheDirectory(appContext),
PathUtils.getDataDirectory(appContext));
}
};
//步骤19、通过线程池提交Callable并返回一个Future实例。
initResultFuture = Executors.newSingleThreadExecutor().submit(initTask);
}
//…
//步骤20、提取apk中assets文件为未压缩的在磁盘中,上面步骤14调用。
private ResourceExtractor initResources(@NonNull Context applicationContext) {
ResourceExtractor resourceExtractor = null;
//步骤21、如果是debug或jit模式resourceExtractor才不为空。
if (BuildConfig.DEBUG || BuildConfig.JIT_RELEASE) {
//步骤22、路径为context.getDir(“flutter”),也就是私有沙盒下的flutter目录。
final String dataDirPath = PathUtils.getDataDirectory(applicationContext);
//步骤23、获取apk的应用包名。
final String packageName = applicationContext.getPackageName();
final PackageManager packageManager = applicationContext.getPackageManager();
final AssetManager assetManager = applicationContext.getResources().getAssets();
//步骤24、拿着一堆apk信息和目录实例化一个ResourceExtractor供后续调用。
resourceExtractor =
new ResourceExtractor(dataDirPath, packageName, packageManager, assetManager);
//步骤25、debug及jit模式填充路径。flutterApplicationInfo来自上面步骤11实例化构建。
//默认资源路径:flutter_assets/vm_snapshot_data
//默认资源路径:flutter_assets/isolate_snapshot_data
//默认资源路径:flutter_assets/kernel_blob.bin
resourceExtractor
.addResource(fullAssetPathFrom(flutterApplicationInfo.vmSnapshotData))
.addResource(fullAssetPathFrom(flutterApplicationInfo.isolateSnapshotData))
.addResource(fullAssetPathFrom(DEFAULT_KERNEL_BLOB));
//步骤26、开始执行resourceExtractor。
resourceExtractor.start();
}
return resourceExtractor;
}
//…
}
到此初始化就异步开始了,我们需要阻塞等待他的执行结束,如下:
public class FlutterLoader {
//…
//步骤27、阻塞直到上面步骤10的startInitialization方法执行完毕。
//一般紧挨在startInitialization方法后调用。
public void ensureInitializationComplete(
@NonNull Context applicationContext, @Nullable String[] args) {
//…
try {
//步骤28、阻塞等待上面步骤19的线程池Callable initTask执行完毕。
InitResult result = initResultFuture.get();
//步骤29、构建一堆参数供初始化使用。
List shellArgs = new ArrayList<>();
shellArgs.add(“–icu-symbol-prefix=_binary_icudtl_dat”);
//步30、flutterApplicationInfo在上面步骤11构建。
//路径为:[ApplicationInfo.nativeLibraryDir]/libflutter.so
shellArgs.add(
“–icu-native-lib-path=”
-
flutterApplicationInfo.nativeLibraryDir
-
File.separator
-
DEFAULT_LIBRARY);
if (args != null) {
//步31、把启动FlutterActivity或FlutterFragment时intent中传递的dartVmArgs参数加入列表。
//譬如:trace-startup=true等
Collections.addAll(shellArgs, args);
}
String kernelPath = null;
//步32、debug、jit模式设置一些参数路径啥的。
if (BuildConfig.DEBUG || BuildConfig.JIT_RELEASE) {
String snapshotAssetPath =
result.dataDirPath + File.separator + flutterApplicationInfo.flutterAssetsDir;
kernelPath = snapshotAssetPath + File.separator + DEFAULT_KERNEL_BLOB;
shellArgs.add(“–” + SNAPSHOT_ASSET_PATH_KEY + “=” + snapshotAssetPath);
shellArgs.add(“–” + VM_SNAPSHOT_DATA_KEY + “=” + flutterApplicationInfo.vmSnapshotData);
shellArgs.add(
“–” + ISOLATE_SNAPSHOT_DATA_KEY + “=” + flutterApplicationInfo.isolateSnapshotData);
} else {
//步骤33、release模式重点!!!!
//前几天还有网友微信我说想让分析flutter appso热更新,这就是核心啊,就这一句话。
//–aot-shared-library-name=缺省libapp.so,可以通过清单文件meta-data配置so的名称为自定义值,配置name为io.flutter.embedding.engine.loader.FlutterLoader.aot-shared-library-name。
shellArgs.add(
“–” + AOT_SHARED_LIBRARY_NAME + “=” + flutterApplicationInfo.aotSharedLibraryName);
//步骤34、–aot-shared-library-name再配置一个apk安装后包路径下so的全路径地址。
shellArgs.add(
“–”
- AOT_SHARED_LIBRARY_NAME
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。







既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)

最后
文章所有资料全部已经打包整理好,另外小编手头上整理了大量Android架构师全套学习资料,Android核心高级技术PDF文档+全套高级学习资料+视频+2021 BAT 大厂面试真题解析
资料展示:




一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!**](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
更多推荐



所有评论(0)