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()

1.2 onCreate()

总结:


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 源码分析 初始化过程的主要内容,如果未能解决你的问题,请参考以下文章

Android——Qigsaw 源码分析 初始化过程

Android——Qigsaw 源码分析 初始化过程

Android——Qigsaw 源码分析 初始化过程

Android——Qigsaw 源码分析 初始化过程

Android——Qigsaw 源码分析 加载过程

Android——Qigsaw 源码分析 加载过程