Android11 resources.arsc不支持压缩问题解决
问题原因
这里先放下根本原因:Android R+不在允许app压缩resource.asrc。
出问题的代码
这里简单描述下一些前置的背景知识:
- 插件也是一个独立的apk
- Neptune框架的插件是可以访问宿主资源的
- 插件安装到宿主需要校验包名和版本号等信息
以下的代码,就是主动获取插件Apk的一些基本信息,包括包名、版本号等。
PackageManager pm = context.getPackageManager(); PackageInfo pkgInfo = pm.getPackageArchiveInfo(apkFilePath, PackageManager.GET_ACTIVITIES);
这个代码在compileSdkVersion、targetSdkVersion为30以下的时候,并不会有任何的问题。
DEBUG结果
这里放下当插件的compileSdkVersion、targetSdkVersion升级到30后出现的崩溃信息:
Targeting R+ (version 30 and above) requires the resources.arsc of installed APKs to be stored uncompressed and aligned on a 4-byte boundary.
相关代码请见:
private ParseResult parseBaseApk(ParseInput input, File apkFile,
String codePath, AssetManager assets, int flags) {
final String apkPath = apkFile.getAbsolutePath();
...忽略了大部分的代码...
final ParsingPackage pkg = result.getResult();
// 抛出异常的地方
if (assets.containsAllocatedTable()) {
final ParseResult<?> deferResult = input.deferError(
"Targeting R+ (version " + Build.VERSION_CODES.R + " and above) requires"
+ " the resources.arsc of installed APKs to be stored uncompressed"
+ " and aligned on a 4-byte boundary",
DeferredError.RESOURCES_ARSC_COMPRESSED);
if (deferResult.isError()) {
return input.error(INSTALL_PARSE_FAILED_RESOURCES_ARSC_COMPRESSED,
deferResult.getErrorMessage());
}
}
}
官方文档
Apps that target Android 11 (API level 30) or higher can’t be installed if they contain a compressed resources.arsc
file or if this file is not aligned on a 4-byte boundary. This file cannot by memory-mapped by the system if either of these conditions is present. Resources tables that cannot be memory-mapped must be read into a buffer in RAM resulting in unnecessary memory pressure on the system and greatly increased device RAM usage.
如果以 Android 11(API 级别 30)或更高版本为目标平台的应用包含压缩的 resources.arsc
文件或者如果此文件未按 4 字节边界对齐,应用将无法安装。如果存在其中任意一种情况,系统将无法对此文件进行内存映射。无法进行内存映射的资源表必须读入 RAM 中的缓冲区,从而给系统造成不必要的内存压力,并大大增加设备的 RAM 使用量。
验证
找一个无法安装的插件验证下:
➜ 30.0.2 ./zipalign -c -v 4 ~/Desktop/com.qiyi.xxx.apk
5078317 res/xml/filepaths.xml (OK – compressed)
5078776 res/xml/network_security_config.xml (OK – compressed)
5079095 res/xml/network_security_config_release.xml (OK – compressed)
5079286 resources.arsc (OK – compressed) # 被压缩了
Verification succesful
- 最后一行:
resources.arsc (OK - compressed)
。
看起来是官方限制死了。当Android工程的compileSdkVersion、targetSdkVersion升级到30,强制要求resources.arsc不能被压缩。
解决方案
关于资源编译相关的部分,可以先从booster分析-App资源压缩了解下基本原理。
流程分析
插件框架的Gradle插件主要是用于上述*.ap_
生成后,对资源文件进行修改、删除、添加的操作,以便固定资源id和剔除不必要的资源。
代码分析
核心代码:com.qiyi.plugin.hooker.TaskHookerManager#reWriteArscFile
private void reWriteArscFile(ProcessAndroidResources par, ApkVariant variant) {
// 删除多余的资源 ZipUtil.with(apFile).deleteAll(filteredResources + updatedResources) // 将有变动的资源重新使用aapt add回去 addUpdatedResources(aaptPath, resourcesDir, apFile, updatedResources)
} /** 重新更新资源 - 通过验证,使用该命令添加的资源默认会被压缩 * $ aapt add resources.ap_ file1 file2 */ def addUpdatedResources(String aaptPath, File resourcesDir, File apFile, Collection updatedResources) { project.exec { executable aaptPath workingDir resourcesDir args 'add', apFile.path args updatedResources standardOutput = System.out errorOutput = System.err } }
从验证的结果来看,aapt add resources.ap_ file1 file2
默认会压缩。
修复方案
从AAPT的文档中,没有发现add的命令支持不压缩的方案,我们只能手动的通过Java的Zip API将resources.arsc
以存档的形式补充回去。其他的资源还是老样子添加即可。
- 修复方案:将压缩的方式改为文档存储的形式。
ZIPENTRY
STORED
:未压缩条目的压缩方法。DEFLATED
:压缩条目的压缩方法。
代码实现
这里就不放代码了,具体实现可以参见:
- Android资源混淆工具(知名库):
- 或者这个:
- Java 实现文件【夹】压缩
- Zip压缩zipOut.setMethod(ZipOutputStream.STORED);如何处理
- ╮(╯▽╰)╭代码全靠抄……
附录
- Android Gradle plugin release notes
- iBotPeaches/Apktool
- 行为变更:以 Android 11 为目标平台的应用
- shwenzhang/AndResGuard:targetSdkVersion 设置成30,在R系统上无法安装
- Android R+不在允许app压缩resource.asrc。
- [core] Stop to compress resources.asrc when targeting R+(version 30 a…
- resources.arsc压缩会影响性能吗?
- Java appending files into a zip
- Is app-release.apk zipaligned apk?
APK瘦身
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/18649,转载请注明出处。
评论0