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移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后

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

资料展示:

image

image

image

image

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

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、安卓逆向、云计算

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐