Qigsaw拓展功能

在实际开发过程中,Android App Bundle所支持的功能特性并不满足我们需求。因此,Qigsaw在Android App Bundle基础上拓展了几个功能。

  • Split APKs的Application初始化。
  • Split APKs的Content Provider动态加载。
  • 多进程支持。
  • 通过Tinker patch完成split APKs热更新。在此,我们首先介绍Qigsaw多进程功能。以下图场景为例。

multiple_processes_support_sample

依据Qigsaw安装、加载split APKs原则,当游戏APK安装完成后,就会在主进程完成加载。在游戏APK中有两个Activity,他们所处进程不同。当启动GameActivity01时,页面正常启动。但当启动GameActivity02,您的App会出现崩溃。原因是GameActivity02运行在:game进程,游戏APK仅在主进程加载,并未在:game进程加载,因此系统会抛出ClassNotFoundException异常。

为解决这类问题,Qigsaw提供了如下解决方案。

  • 在进程启动之初即Applicatin#attachBaseContext调用时,加载所有已安装splits。
  • Hook PathClassLoader。第一种方案解决的场景是:game进程首次启动,即启动GameActivity02之前:game进程从未启动过。

第二种方案解决的场景是:game进程已经启动并正在运行。

Hook PathClassLoader具体做了如下事情。

  • 当出现ClassNotFoundException时,判断该类是否为splits四大组件。
  • 当异常类为splits四大组件时,加载所有已安装未加载split APKs。
  • 如加载完所有已安装未加载split APKs后依然出现ClassNotFoundException异常,则返回空四大组件类,防止进程崩溃。

如果split APKs某Activity的exported熟悉为true,那么该Activity可能会在split未安装的情况下被外界调起。当出现这种情况时,Qigsaw返回空Activity类防止进程崩溃。

国内很多App都接入Tinker用于修复线上bug,爱奇艺同样也接入。Qigsaw本身提供热更新能力,但在实际开发过程中发现,Qigsaw能借助Tinker Patch热更新split APKs,提升开发效率。

split_info_json_in_base

Qigsaw在打包过程中会生成关于包含split信息的.json文件,该文件存储在base APK的assets目录下。其命名规则为App版本号_Split信息版本号.json

json文件记录的内容如下。

  1. {
  2. "qigsawId": "1.0.0_ddddf54",
  3. "appVersionName": "1.0.0",
  4. "splits": [
  5. {
  6. "splitName": "java",
  7. "url": "assets://java.zip",
  8. "builtIn": true,
  9. "size": 13915,
  10. "version": "1.1@1",
  11. "md5": "9ea0f98381dea0d16a313ea9c09cc4aa",
  12. "workProcesses": [
  13. ":qigsaw",
  14. ""
  15. ],
  16. "minSdkVersion": 14,
  17. "dexNumber": 4
  18. },
  19. ...
  20. ...
  21. }

该文件记录着splits版本号以及下载地址,如果Tinker开启资源修复,我们就可以通过tinker patch更新该json文件,以此达到热更新splits目的。