no compressed resourrce.arsc files

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());
    }
}

}

官方文档

详见:Compressed resource files

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 使用量。

验证

zipalign 是一种归档对齐工具,可对 Android 应用 (APK) 文件提供重要的优化。

找一个无法安装的插件验证下:

➜ 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

Class ZipEntry文档

  • STORED:未压缩条目的压缩方法。
  • DEFLATED:压缩条目的压缩方法。

代码实现

这里就不放代码了,具体实现可以参见:

附录

APK瘦身

下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/18649,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?