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.
vivo手机不支持adb install-multipl命令。
这里我们重点介绍第二种安装方式,Android 5.0提供PackageInstaller用于安装Base APK和Split APKs。
当第三方应用通过PackageInstaller在应用运行期安装Split APKs时,系统会启动安装器界面供用户选择是否安装此次更新。

在用户选择安装后,应用将会被系统“杀死”。当应用再次启动之后,Split APKs就会生效。
在我们实际测试过程中,某些国产手机对PackageInstaller有改动,导致无法正常安装Split APKs。
系统应用可以静默安装Split APKs,且当Split APKs安装完成后,可以决定是否“杀死“应用进程。
1. public static class SessionParams implements Parcelable {
3. ...
5. /** {@hide} */
6. @SystemApi
7. public void setDontKillApp(boolean dontKillApp) {
8. if (dontKillApp) {
9. installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
10. } else {
11. installFlags &= ~PackageManager.INSTALL_DONT_KILL_APP;
12. }
13. }
14. ...
15. ...
16. }
SessionParams是PackageInstaller内部类,setDontKillApp可决定当APK安装完成后是否杀死应用进程。setDontKillApp属于系统Api,因此第三方应用无法调用。
Split APKs加载
应用进程所使用到的ClassLoader和Resources均在LoadedAPK中创建。

通过Android 9.0 LoadedAPK源码片段,我们一起了解下Split APKs加载过程。
ClassLoader创建。

通过createOrUpdateClassLoaderLocked方法名,可以知道该方法是用于创建和更新ClassLoader。该方法有两个核心步骤。
- 如果
mClassLoader为空,则创建PathClassLoader实例。 - 如果
addedPaths不为空,则更新PathClassLoader实例。
该方法指明,应用进程是可以动态加载Split APKs代码。
Resources创建。

通过getResources方法代码片段,可知Split APKs的资源路径作为mResources创建参数。
关于更多Split APKs加载原理细节,请阅读相关Android源码。
