更新了
之前因为换了一家公司,这个项目也就暂停更新了,现在被裁所以有时间做一些更新()。虽说是更新,只是完善了demo,修了个之前急着改导致的bug,以及将库发布到jitpack方便使用,也算是练习一下新技术。
具体可以查看github上的README,也因为没什么功能更新,RELEASE写的很简陋,见谅!
为什么有这篇文章
最近一直在修bug,都是琐碎的ui或者交互方面的,倒是用户那边反应有游戏下载了安装不了,仔细检查发现用户下载的是xapk,并且里面包含两个apk,之前我们适配的xapk都是一个apk加上要放到Android/obb目录下的资源,然后经过几天的调研,实现,终于适配了这种xapk,正好在假期里记录一下。
XAPK 简介
xapk并不是一种替代apk的格式,而是将apk和其他文件打包成一个文件,方便下载,具体的说明,可以参考这篇文章:What is xapk.
之前我们已经适配了单apk加上obb资源文件,而现在我所做的,就是适配多apk的xapk。
调研
一开始看到多apk,我就直接试着一个一个安装,结果主apk安装了打开闪退,而另一个apk安装失败,这下就只好google查怎么安装,但搜到的主要就是上面给出的链接,只有介绍,没有实际安装的逻辑。查了许久一无所获,突然发现xapk里除了两个apk,还有icon图片文件和manifest.json文件,感觉到这个json文件,可能包含一些信息,打开发现其中提到了split_apk,然后通过这个进行搜索,果然发现了问题所在。
多个apk的xapk的出现,主要是因为google新推的app bundle机制,通过拆分资源,实现减小apk包大小的目的。而这里我遇到的是老任的马里奥赛车xapk,包含一个主apk和一个config apk,然后我们就顺着这个思路查找对应的安装方法,具体的话参考:Android PackageInstaller.
按照文档的说明,这样的多apk,我们得自己实现安装,具体的可以参考官方文档:InstallApkSeesionApi.
开始撸代码
按照demo,我们就可以实现安装多apk了,但这还不够,因为之前已经适配了单apk加上其他资源文件的xapk,所以我们需要兼容两者.
第一步我们得判断是单apk还是多apk,这里的话我是使用了第三方的zip库,地址:zt-zip。然后解压xapk,判断其中包含的apk的数量,方便后续进行不同的处理。这里关于如何处理obb资源文件,可以直接在这一步处理。
然后就是对单apk的xapk的处理和多apk的xapk的处理,因为是不同处理方式,我们可以定义一个XapkInstaller接口,然后分别实现不同的子类去处理不同的情况就可以了。这样的话,上一步的判断逻辑,我们可以实现一个XapkInstallerFactory进行处理,然后返回不同的XapkInstaller,以利用oo的多态机制。
return if (apkSize > 1) {
MultiApkXapkInstaller(xapkFilePath, unzipOutputDir)
} else {
SingleApkXapkInstaller(xapkFilePath, unzipOutputDir)
}
(注:实际代码中,我是定义XapkInstaller的抽象类,主要是为了统一处理异常,如果读者有什么更好的想法,欢迎指导。)
结语
到这里我们就完成了多apk的xapk的适配,我这边也将代码上传到了github上,地址:XAPKInstaller,主要代码都是用kotlin实现的,如果喜欢还请star支持一下。