Android——Qigsaw 源码分析 初始化过程
Posted 化作孤岛的瓜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android——Qigsaw 源码分析 初始化过程相关的知识,希望对你有一定的参考价值。
上一章节描述了Qigsaw编译期做的事情,后面的工作就是运行期进行的初始化,加载,和安装插件的过程。本文主要分析初始化过程。
通过官方文档:https://github.com/iqiyi/Qigsaw/blob/master/README.zh-CN.md
中可以了解到,插件安装过程在QigsawApplication中。
目录
1.QigsawApplication
1.1 attachBaseContext()
SplitConfiguration configuration = SplitConfiguration.newBuilder()
.splitLoadMode(SplitLoad.MULTIPLE_CLASSLOADER)
.workProcesses(workProcesses)
// .forbiddenWorkProcesses(forbiddenWorkProcesses)
.logger(new SampleLogger())
.verifySignature(true)
.loadReporter(new SampleSplitLoadReporter(this))
.installReporter(new SampleSplitInstallReporter(this))
.uninstallReporter(new SampleSplitUninstallReporter(this))
.updateReporter(new SampleSplitUpdateReporter(this))
.obtainUserConfirmationDialogClass(SampleObtainUserConfirmationDialog.class)
.build();
1.构建SplitConfiguration配置参数,可选的配置包括
- splitLoadMode (单/多classloader加载模式)
- workProcesses (工作进程,与forbiddenWorkProcesses互斥)
- logger(日志输出)
- verifySignature(是否验证插件包签名)
- 加载/安装/卸载/更新监听器,插件弹窗。
2.执行Qigsaw.install() → Qigsaw.instance().onBaseContextAttached()
private void onBaseContextAttached()
SplitBaseInfoProvider.setPackageName(context.getPackageName());
boolean qigsawMode = SplitBaseInfoProvider.isQigsawMode();
if (isMainProcess)
SplitUpdateReporterManager.install(splitConfiguration.updateReporter == null ? new DefaultSplitUpdateReporter(context) : splitConfiguration.updateReporter);
//init SplitLoadManager and hook PatchCLassLoader.
SplitLoadManagerService.install(
context,
splitConfiguration.splitLoadMode,
qigsawMode,
isMainProcess,
currentProcessName,
splitConfiguration.workProcesses,
splitConfiguration.forbiddenWorkProcesses);
//data may be cached.
SplitLoadManagerService.getInstance().clear();
SplitLoadManagerService.getInstance().injectPathClassloader();
//data may be cached.
AABExtension.getInstance().clear();
AABExtension.getInstance().createAndActiveSplitApplication(context, qigsawMode);
SplitCompat.install(context);
- SplitBaseInfoProvider 设置包名
SplitBaseInfoProvider(Split组件信息提供)通过反射生成编译过程中GenerateQigsawConfig[Task]生成的QigsawConfig类,通过反射拿到其中注入的各种属性
- SplitLoadManagerService.install()
SplitLoadManagerService (加载管理器) 创建实现类SplitLoadManagerImpl
初始化SplitInfoManagerService → 初始化SplitInfoManagerImpl(实现类) 绑定 SplitInfoVersionManager(版本控制)
SplitInfoManagerImpl中通过获取AssetManager解析Assets目录下的qigsaw/qigsaw_1.0.0_1.0.0.json信息文件(前文编译过程[CreateSplitDetailsFileTask]生成的,存疑,怎么转移过来的?),解析成SplitDetails,并提供各种方法给外部调用以获取插件信息。
初始化SplitPathManager:
通过qigsawId:1.0.0_a8414bd和路径/data/user/0/com.iqiyi.qigsaw.sample/app_qigsaw初始化路径管理器
3.SplitLoadManagerService清除加载的插件缓存数据
清除loadedSplits缓存
4.SplitLoadManagerService → SplitLoadManagerImpl.injectPathClassloader()
通过Context注入classLoader:SplitDelegateClassloader(继承自PathClassLoader),并创建DefaultClassNotFoundInterceptor用于findClass的失败处理,作为插件的class查找使用
5.AABExtension.getInstance().createAndActiveSplitApplication(context, qigsawMode)
AABExtension负责管理application和provider,主要是通过反射的方式创建和激活。 通过SplitComponentInfoProvider→ComponentInfoManager获取编译过程中SplitComponentTransform[Task]保存的ComponentInfo中的Split四大组件信息。
1.2 onCreate()
AABExtension.getInstance().onApplicationCreate();
SplitLoadReporterManager.install(splitConfiguration.loadReporter == null ? new DefaultSplitLoadReporter(context) : splitConfiguration.loadReporter);
//only work in main process!
if (isMainProcess)
SplitInstallReporterManager.install(splitConfiguration.installReporter == null ? new DefaultSplitInstallReporter(context) : splitConfiguration.installReporter);
SplitUninstallReporterManager.install(splitConfiguration.uninstallReporter == null ? new DefaultSplitUninstallReporter(context) : splitConfiguration.uninstallReporter);
SplitApkInstaller.install(
context,
downloader,
splitConfiguration.obtainUserConfirmationDialogClass,
splitConfiguration.verifySignature);
SplitApkInstaller.startUninstallSplits(context);
if (Looper.myLooper() != null)
Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler()
@Override
public boolean queueIdle()
cleanStaleSplits(context);
return false;
);
else
cleanStaleSplits(context);
onApplicationCreated = true;
执行Qigsaw.onApplicationCreated()→Qigsaw.onCreate()
1.AABExtension.getInstance().onApplicationCreate()
遍历AABExtension中的aabApplications,分别执行onCreate()
2.初始化组件加载,安装,卸载回调
分别是SplitInstallReporterManager,SplitInstallReporterManager,SplitUninstallReporterManager
首先取SplitConfiguration 主动设置的,没有的话new默认的。
它们会在对应的时机执行回调逻辑。
3.初始化安装器SplitApkInstaller
内部维持一个抽象类实例:SplitInstallSupervisor,其实现类为SplitInstallSupervisorImpl,负责具体的安装和卸载组件任务。
4.SplitApkInstaller执行卸载任务
主要是读取SplitPendingUninstallManager中需要卸载的组件,然后删掉对应的文件路径。
SplitApkInstaller.startUninstallSplits(context) → SplitInstallSupervisor.startUninstall()
首先在SplitPendingUninstallManager中判断路径/data/user/0/com.iqiyi.qigsaw.sample/app_qigsaw/1.0.0_a8414bd/uninstall/uninstallsplits.info
的文件(存储了需要卸载的组件信息),如果存在则执行后续的卸载操作,如果安装过,删除目录下的文件。
5.开启清理服务
通过SplitPathManager的clearCache方法去清理/data/user/0/com.iqiyi.qigsaw.sample/app_qigsaw下与当前操作id不同的残留文件,防止臃肿。
6.preload加载组件Task
回到Qigsaw.onApplicationCreated()->Qigsaw.preloadInstalledSplits(Arrays.asList(QigsawConfig.DYNAMIC_FEATURES));
安装过程的入口,主要在下一篇详细说明。
总结:
初始化过程主要是进行各个组件的初始化工作,初始化配置(获取QigsawConfig),设置各类监听器,初始化后续用到的加载器(SplitLoadManagerService),安装/卸载器(SplitApkInstaller)。然后执行组件的安装工作。
后续继续分析加载和安装过程。
以上是关于Android——Qigsaw 源码分析 初始化过程的主要内容,如果未能解决你的问题,请参考以下文章