Android——Qigsaw 源码分析 安装过程
Posted 化作孤岛的瓜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android——Qigsaw 源码分析 安装过程相关的知识,希望对你有一定的参考价值。
前言
在编译,初始化,加载的准备工作都结束以后,就到了插件的安装步骤。
本文按调用顺序来分析具体的安装步骤。
在官方demo下,可以看到QigsawInstaller中实际执行安装的步骤:
SplitInstallManager.startInstall
↓
SplitInstallManagerImpl.startInstall(SplitInstallRequest request)
↓如果未安装
SplitInstallService.startInstall(List<String> moduleNames)
这个SplitInstallService是playcoelibrary下的
↓
RemoteManager.bindService
会把所有的任务收集到mPendingTasks里
↓post了一个绑定服务
BindServiceTask.execute()
↓
RemoteManager.bindServiceInternal(RemoteTask remoteTask)
首先判断服务是否绑定成功,如果绑定成功了直接执行task
如果还没绑定启动绑定服务
↓绑定
ServiceConnectionImpl
↓绑定成功onServiceConnected(ComponentName name, IBinder service)
post一个绑定成功的task ServiceConnectedTask
↓执行并清空RemoteManager内所有的mPendingTasks。
执行安装任务StartInstallTask
↓
mSplitInstallService.mSplitRemoteManager.getIInterface().startInstall()
SplitInstallService(playcoelibrary)内部有一个安装服务代理实例RemoteManager<ISplitInstallServiceProxy> mSplitRemoteManager,其实现类为SplitRemoteImpl,通过AIDL委托给
com.iqiyi.android.qigsaw.core.splitinstall.remote.SplitInstallService来实现
↓
小结
这部分过程主要是,通过AIDL建立远端Rpc通信:
SplitInstallService(playcoelibrary下的,Server端)
SplitInstallService(splitinstaller下的,Client端)
将真正的安装操作委派给后面的SplitInstallSupervisorImpl实现
↓
安装的具体实现:(注意这个SplitInstallService不是playcoelibrary的module下的,而是splitinstaller下的)
SplitInstallService(splitinstaller):
↓
post一个安装任务OnStartInstallTask
↓
SplitInstallSupervisor.install()
最终还是通过SplitInstallSupervisor执行具体的安装任务,这个SplitInstallSupervisor在前文介绍的初始化过程Qigsaw的onCreated也有用到:
private void onCreated()
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;
↓安装实现类
首先开始进行下载过程
SplitInstallSupervisorImpl.startInstall(List<Bundle> moduleNames, Callback callback)
主要是获取编译过程生产的splitApk然后复制至安装目录中/data/data/pkgName/app_qigsaw/$qigsawid/。
↓
SplitInstallSupervisorImpl.onPreInstallSplits(List<String> moduleNames)
1.校验aab是否包含了当前split
2.校验module名字是否为空,是否包含在aab记录的dynamicFeatures中
↓
SplitInstallSupervisorImpl.startDownloadSplits(final List<String> moduleNames,
final List<SplitInfo> needInstallSplits,
final Callback callback)
创建下载任务,每一个任务有一个事物id:sessionId,根据id和状态两个纬度做下载生命周期控制。
↓
委托给外部代理类SampleDownloader进行下载,如果已经下载过的会直接执行安装
↓下载完成,执行安装流程
SplitSessionInstallerImpl.install(int sessionId, List<SplitInfo> splitInfoList)
↓
执行安装任务
SplitInstallTask.run()
↓
安装任务实现类
- SplitInstallerImpl.install(boolean startInstall, @NonNull SplitInfo info)
- 首先拿到之前保存在私有目录下的apk文件
- 检查md5和签名校验。
- 通过DexClassLoader加载安装apk。
- 动态加载Oat文件(这一段很难懂,在20~26版本做了处理,针对oppo,vivo,EEBBk步步高三个制造商,检查oat的文件是否是elf格式,并用specialMarkFile做特殊标记)
- 构建markFile作为安装标记
↓
安装完成后,将结果回调回去。
总结:
首先通过AIDL建立RPC通信,将安装任务从代理类SplitInstallService(Server)传递给执行类SplitInstallService(Client),然后最终通过SplitInstallSupervisorImpl执行具体的安装逻辑,依靠DexClassLoader实现动态安装。
链接:
Android——Qigsaw 源码分析(一) 编译过程_化身孤岛的瓜-CSDN博客
Android——Qigsaw 源码分析(二) 初始化过程_化身孤岛的瓜-CSDN博客
以上是关于Android——Qigsaw 源码分析 安装过程的主要内容,如果未能解决你的问题,请参考以下文章