解决SDK>=30时,APK反编译后重打包安装失败的问题

安装报错: Failed parse during installPackageLI: Targeting R+ (version 30 and above) requires the resources.arsc of installed APKs to be stored uncompressed and aligned on a 4-byte boundary

1 问题描述

在解包apk后,笔者对部分smali进行了修改,然后使用apktool重新打包,然后手动签名,用adb发现会安装失败,报错信息如下:

/androiddevissues-02/screen.webp
报错信息

网上搜索之后发现,该问题是由resource.arsc文件的压缩导致的,该文件是apk的资源文件,是一个二进制文件,用于存储apk的资源信息,如图片、布局等,该文件在安装时会被解包,所以在安装时,该文件必须是未压缩的,且必须是4字节对齐的,否则会导致安装失败。

2 解决方案

了解了问题原因所在后,我们只需对apk进行重新打包,使得resource.arsc文件是未压缩的,且4字节对齐即可。

注意

apktool最新版(v2.6.1)已经能够自动对SDK版本大于等于30的项目打包时跳过resource.arsc文件的压缩。

如果使用的是旧版或者自己编译的apktool,可以在打包apk时指定参数-api 30或者在解包文件夹的apktool.yml文件的doNotCompress节点中追加- resources.arsc,即可跳过resource.arsc文件的压缩。

2.1 zipalign进行4字节对齐

zipalign是Android SDK中的一个工具,用于对apk进行4字节对齐,使用方法如下:

1
zipalign -f -v 4 input.apk output.apk

其中,-f表示强制覆盖,-v表示显示详细信息,4表示4字节对齐,input.apk表示输入的apk文件,output.apk表示输出的apk文件。

2.2 apksigner进行签名

apksigner是Android SDK中的一个工具,用于对apk进行签名,使用方法如下:

1
apksigner sign --ks my-release-key.jks --out output.apk input.apk

其中,–ks表示keystore文件,–out表示输出的apk文件,input.apk表示输入的apk文件。

  • [注意]
    • 请不要使用jarsigner进行签名,因为jarsigner只能进行V1签名,而V2签名是SDK>=24时才支持的,所以使用jarsigner签名后,安装时会报错:INSTALL_PARSE_FAILED_NO_CERTIFICATES
给作者倒杯卡布奇诺 ~
Albresky 支付宝支付宝
Albresky 微信微信