1. Qigsaw插件结构详解

Qigsaw是爱奇艺自主研发的动态化结构,其核心优势如下:

  1. 运用Android App Bundle开发套件,极速开发体会。
  2. 支撑Android App Bundle一切功用特性,”山寨”Play Core Library揭露接口完结,开发者阅览官方文档即可愉快开发。
  3. 任何进程均可动态加载插件,支撑Android四大组件动态加载。
  4. 假如您的运用有出海需求,可无缝切换至Android App Bundle计划。
  5. 仅一处Hook,少量私有API拜访,确保结构稳定性。

Android动态化计划,在国内已蓬勃开展数年之久,其核心目的是减少运用包体积,提升运用装置率。Google在减少运用包体积上的探索也从未停息,下面咱们一起来看看Google在这方面的努力。

2. Google减少运用包体积计划演进

3. Multiple APK

Qigsaw插件框架初探

上图中生成的产品,经过文件名咱们能够很清楚知道该APK作用于何种装备的设备。Android设备的多样性,导致Multiple APK并未朝着Google期待的方向开展。由于您有可能为每个版别构建数百个APKs,大大下降迭代效率。国外开发者对此也并不感冒,这也成为Google的一块心病。

4. Android App Bundle

Android App Bundle是一种全新的运用上传格局(.aab),它包含一切编译代码和资源。当您上传aab文件至Google Play后,Google Play将aab文件拆分成一系列APKs并签名。

Qigsaw插件框架初探

此外,您也能够在运用项目中增加dynamic feature模块,这些模块并不需求在运用首次装置时一起被下载装置。您能够经过运用Play Core Libray在运用运转进程中动态装置dynamic feature。dynamic feature相似国内插件化供给的能力,但dynamic feature功用更强大。

Qigsaw插件框架初探

经过上图,能够看到dynamic feature能够根据设备装备选取对应的Configuration Split APKs,如此能够进一步减小dynamic feature装置包体积。

更多关于Android App Bundle细节,请阅览官方文档,本文不再赘述。Android App Bundle之所以能够支撑运用运转期间装置dynamic feature,得益于Android 5.0推出的Split APKs功用。

5. Split APKs

Split APKs是Android 5.0引入的一种全新运用装置机制,其目的是为处理APK体积日益增大问题。Split APK能够将一个完整巨大的APK按照CPU架构、屏幕密度等维度拆分成多个独立APKs。当运用APK下载更新时,根据当时设备装备选取对应装备APKs装置即可。

Android 5.0之前,一个APK代表一个运用。在Split APKs面世之后,一个运用可能对应多个APKs。一切Split APKs拥有相同包名和签名。

Android供给两种办法装置Split APKs。

  1. adb install-multiple [base-apk, split1-apk]
  2. PackageInstaller.

运用进程所运用到的ClassLoader和Resources均在LoadedAPK中创立。

Qigsaw插件框架初探

经过Android 9.0 LoadedAPK源码片段,咱们一起了解下Split APKs加载进程。

5.1 ClassLoader创立

Qigsaw插件框架初探

经过createOrUpdateClassLoaderLocked办法名,能够知道该办法是用于创立和更新ClassLoader。该办法有两个核心进程。

  1. 假如mClassLoader为空,则创立PathClassLoader实例。
  2. 假如addedPaths不为空,则更新PathClassLoader实例。

该办法指明,运用进程是能够动态加载Split APKs代码。

5.2 Resources创立

Qigsaw插件框架初探

经过getResources办法代码片段,可知Split APKs的资源路径作为mResources创立参数。

关于更多Split APKs加载原理细节,请阅览相关Android源码。

5.3 Play Core Library

文章开端介绍Qigsaw核心优势有说到,Qigsaw”山寨”Play Core Library揭露接口完结,开发者阅览其官方文档即可开发。因而,在此首要介绍下Play Core Library作业流程。

Qigsaw插件框架初探

当爱奇艺App在运转进程中,用户需求运用游戏插件,会阅历以下进程。

  1. 爱奇艺App经过Play Core Library建议游戏APK装置恳求。
  2. 当Google Play收到恳求后,首要恳求游戏APK相关数据信息,恳求成功后开端下载并装置游戏APK。
  3. 在恳求、下载以及装置整个进程中,Google Play会将整个进程一切状况回来给爱奇艺App,包含恳求结果、下载进展、装置结果等。
  4. 当装置完结今后,爱奇艺App就能够运用游戏APK。

在Android 7.0版别之前,当Split APK装置完结之后,运用无法当即运用Split APK。因而Play Core Library供给SplitCompat模式让App可当即运用Split APK。

5.4 Qigsaw开发体会

在开发阶段,开发者运用Android App Bundle原生开发套件即可开发调试Split APKs。

Qigsaw插件框架初探

Android App Bundle为dynamic feature供给全新插件com.android.dynamic-feature,它的编译产品是.apk文件。当您的项目编译完结后,Android Studio经过指令adb install-multiple指令将base apk和split apks装置至您的手机。假如您的开发手机体系版别低于5.0,则会根据当时手机设备组装成一个完整apk文件装置至该手机。

在发布阶段,Qigsaw供给打包插件让开发者享受一条龙服务,开发者不用关怀dynamic feature的上传分发。

Qigsaw插件框架初探

Qigsaw打包插件支撑内置dynamic feature,一切内置dynamic feature都会被拷贝至base apk的assets目录。关于非内置dynamic feature,Qigsaw打包插件会将其上传至CDN服务器,处理事务方后顾之虑。

5.5 Qigsaw原理

Qigsaw凭借Android App Bundle开发套件完结dynamic feature的打包,大大下降Qigsaw开发维护成本。因而Qigsaw关怀的要点落在假如装置加载dynamic feature生成apk上。第三方运用运用PackageInstaller装置split APKs体会极其不友好,且某些国产手机对split APKs功用支撑不完善,所以咱们终究仍是按照一般插件化办法装置加载split APKs。

Qigsaw插件框架初探

根据上图,假如需求动态加载split APKs,需求处理代码、资源以及四大组件的加载。

  • Split APKs代码加载

    针对splits代码加载,Qigsaw选用单类加载器办法,即base APK和split APKs选用同一ClassLoader加载。

Qigsaw插件框架初探

在DexPathList中,为每个split创立对应的ElementNativeLibraryElement实例即可。关于单类加载器更多细节,本文不再赘述,相关原理已非常成熟。

  • Split APKs资源加载

    Splits资源加载相较于代码加载会复杂,由于不同体系版别或不同手机厂商都会存在一些兼容性问题。

Qigsaw插件框架初探

Android Gradle Plugin在资源打包时,会对res目录下资源文件分配一个唯一Id。

Id前两位PP为Package Id,代表运用类型。是体系运用、第三方运用、Instant App或Dynamic Feature等。

Id中间两位TT为Type,代表资源类型。是drawable、layout或string等。

Id后四位EE为Entry,代表该资源次序。

一切第三方运用base APK资源Package Id均为7F,Android App Bundle对splits资源打包时会根据7F依次递减分配Package Id。因而,即使咱们将split APKs资源增加到当时运用Resources实例中,也不会出现资源抵触问题,splits拜访base资源也更加便利。 Instant Apps资源打包是根据7F依次递增。

经过Android App Bundle处理splits资源打包问题,那么splits资源如何加载呢?咱们来看一段代码。

Qigsaw插件框架初探

Qigsaw供给loadResources办法加载split APKs资源。为防止开发者写很多模板代码,Qigsaw打包插件选用字节码操作办法主动写入该办法。

  • Split APKs四大组件加载

    Android App Bundle在Manifest文件合并进程中,会将split APKs manifest文件内容合并至base APK中。因而,一切split APKs四大组件信息都是现已声明在base APK中。Android App Bundle这种处理办法不支撑Manifest更新,例如新增四大组件,所以Qigsaw也不支撑新增四大组件。在正常开发迭代进程中,动态新增splits四大组件需求很少,所以Qigsaw与Android App Bundle特性保持一致。

  • Split APKs装置进程

    Play Core Library是如何装置、加载split APKs,Qigsaw装置、加载split APKs与Play Core Library相似。首要,经过一张图来了解。

Qigsaw插件框架初探

在爱奇艺App运转进程中,当X进程建议装置游戏APK恳求时,会阅历以下进程。

  1. X进程经过Qigsaw Core Library建议游戏APK装置恳求。
  2. 当主进程收到恳求后,开端下载并装置游戏APK。
  3. 在下载、装置整个进程中,Qigsaw Core Library会将整个进程一切状况回来给爱奇艺App,包含下载进展、装置结果等。
  4. 当装置完结今后,爱奇艺App就能够运用游戏APK。

Qigsaw下载、装置split APKs均在主进程处理,split APKs的加载则发生在X进程。Qigsaw装置、加载split APKs原则是,哪个进程建议split APKs装置恳求,就在哪个进程加载split APKs。

  • Qigsaw拓宽功用

    在实际开发进程中,Android App Bundle所支撑的功用特性并不满意咱们需求。因而,Qigsaw在Android App Bundle基础上拓宽了几个功用。

    1. Split APKs的Application初始化。
    2. Split APKs的Content Provider动态加载。
    3. 多进程支撑。
    4. 经过Tinker patch完结split APKs热更新。

    在此,咱们首要介绍Qigsaw多进程功用。以下图场景为例。

Qigsaw插件框架初探