1. Qigsaw插件结构详解
Qigsaw是爱奇艺自主研发的动态化结构,其核心优势如下:
- 运用Android App Bundle开发套件,极速开发体会。
- 支撑Android App Bundle一切功用特性,”山寨”Play Core Library揭露接口完结,开发者阅览官方文档即可愉快开发。
- 任何进程均可动态加载插件,支撑Android四大组件动态加载。
- 假如您的运用有出海需求,可无缝切换至Android App Bundle计划。
- 仅一处Hook,少量私有API拜访,确保结构稳定性。
Android动态化计划,在国内已蓬勃开展数年之久,其核心目的是减少运用包体积,提升运用装置率。Google在减少运用包体积上的探索也从未停息,下面咱们一起来看看Google在这方面的努力。
2. Google减少运用包体积计划演进
3. Multiple APK
上图中生成的产品,经过文件名咱们能够很清楚知道该APK作用于何种装备的设备。Android设备的多样性,导致Multiple APK并未朝着Google期待的方向开展。由于您有可能为每个版别构建数百个APKs,大大下降迭代效率。国外开发者对此也并不感冒,这也成为Google的一块心病。
4. Android App Bundle
Android App Bundle是一种全新的运用上传格局(.aab),它包含一切编译代码和资源。当您上传aab文件至Google Play后,Google Play将aab文件拆分成一系列APKs并签名。
此外,您也能够在运用项目中增加dynamic feature模块,这些模块并不需求在运用首次装置时一起被下载装置。您能够经过运用Play Core Libray在运用运转进程中动态装置dynamic feature。dynamic feature相似国内插件化供给的能力,但dynamic feature功用更强大。
经过上图,能够看到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。
- adb install-multiple [base-apk, split1-apk]
- PackageInstaller.
运用进程所运用到的ClassLoader和Resources均在LoadedAPK
中创立。
经过Android 9.0 LoadedAPK
源码片段,咱们一起了解下Split APKs加载进程。
5.1 ClassLoader创立
经过createOrUpdateClassLoaderLocked
办法名,能够知道该办法是用于创立和更新ClassLoader。该办法有两个核心进程。
- 假如
mClassLoader
为空,则创立PathClassLoader实例。 - 假如
addedPaths
不为空,则更新PathClassLoader实例。
该办法指明,运用进程是能够动态加载Split APKs代码。
5.2 Resources创立
经过getResources
办法代码片段,可知Split APKs的资源路径作为mResources
创立参数。
关于更多Split APKs加载原理细节,请阅览相关Android源码。
5.3 Play Core Library
文章开端介绍Qigsaw核心优势有说到,Qigsaw”山寨”Play Core Library揭露接口完结,开发者阅览其官方文档即可开发。因而,在此首要介绍下Play Core Library作业流程。
当爱奇艺App在运转进程中,用户需求运用游戏插件,会阅历以下进程。
- 爱奇艺App经过Play Core Library建议游戏APK装置恳求。
- 当Google Play收到恳求后,首要恳求游戏APK相关数据信息,恳求成功后开端下载并装置游戏APK。
- 在恳求、下载以及装置整个进程中,Google Play会将整个进程一切状况回来给爱奇艺App,包含恳求结果、下载进展、装置结果等。
- 当装置完结今后,爱奇艺App就能够运用游戏APK。
在Android 7.0版别之前,当Split APK装置完结之后,运用无法当即运用Split APK。因而Play Core Library供给SplitCompat模式让App可当即运用Split APK。
5.4 Qigsaw开发体会
在开发阶段,开发者运用Android App Bundle原生开发套件即可开发调试Split APKs。
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打包插件支撑内置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。
根据上图,假如需求动态加载split APKs,需求处理代码、资源以及四大组件的加载。
-
Split APKs代码加载
针对splits代码加载,Qigsaw选用单类加载器办法,即base APK和split APKs选用同一ClassLoader加载。
在DexPathList中,为每个split创立对应的Element
和NativeLibraryElement
实例即可。关于单类加载器更多细节,本文不再赘述,相关原理已非常成熟。
-
Split APKs资源加载
Splits资源加载相较于代码加载会复杂,由于不同体系版别或不同手机厂商都会存在一些兼容性问题。
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供给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相似。首要,经过一张图来了解。
在爱奇艺App运转进程中,当X
进程建议装置游戏APK恳求时,会阅历以下进程。
-
X
进程经过Qigsaw Core Library建议游戏APK装置恳求。 - 当主进程收到恳求后,开端下载并装置游戏APK。
- 在下载、装置整个进程中,Qigsaw Core Library会将整个进程一切状况回来给爱奇艺App,包含下载进展、装置结果等。
- 当装置完结今后,爱奇艺App就能够运用游戏APK。
Qigsaw下载、装置split APKs均在主进程处理,split APKs的加载则发生在X
进程。Qigsaw装置、加载split APKs原则是,哪个进程建议split APKs装置恳求,就在哪个进程加载split APKs。
-
Qigsaw拓宽功用
在实际开发进程中,Android App Bundle所支撑的功用特性并不满意咱们需求。因而,Qigsaw在Android App Bundle基础上拓宽了几个功用。
- Split APKs的Application初始化。
- Split APKs的Content Provider动态加载。
- 多进程支撑。
- 经过Tinker patch完结split APKs热更新。
在此,咱们首要介绍Qigsaw多进程功用。以下图场景为例。