Android打包
Android打包流程图
打包流程
有了前面这些铺垫,让我们实际看看在执行打包 Task 时,实际还执行了哪些 Task。环境配置如下:
Gradle 5.1.1
Android Gradle Plugin 3.1.2
org.gradle.parallel=true
开启并行编译release
包minifyEnabled true
1 | # --dry-run 表示不实际执行每个 Task |
Task 很多,接下来为大家介绍几个重点的 Task,其余没介绍的感兴趣的同学可以找找对应的实现类,看看它的实现。
preBuild
描述:做一些编译前的检查
一个例子:有的人可能遇到下面的错误
1 | "Android dependency "+ display+ "is set to compileOnly/provided which is not supported" |
这个的原因就是由前面说过的 compileClasspath 和 runtimeClasspath 引起的。
当一个组件因为不同的依赖配置项导致它的 compileClasspath 比如为 1.1.1版本,但他的 runtimeClasspath 是 1.1.2版本,preBuild 就会检测出这个问题并报错我们处理
compileReleaseAidl
类:AidlCompile
描述:内部使用 AidlProcessor 调用 call 方法使用 build-tool 下的 aidl 执行编译。
各类 generate和 merge
这些 Task 允许我们在整个编译工程中动态的生成一些代码,生成好的资源需要和已有的资源进行合并,并且需要注意有可能覆盖已有资源,就不再详细介绍了,
过程
第一步:我们有 app 工程下的 Java 源文件,还有 AIDL
、generate
、R.java
等生成的 Java 源文件,还有本身依赖,源码子工程的 jar 包、远端 aar 解压的 jar 包等一系列二进制文件,源码文件是 javac 需要编译的内容,二进制文件 .jar/.class
则是当 javac 编译遇到一个类名等符号时,如果发现在现有的源文件找不到,该去哪找的集合,对应的 javac 参数就是 -classpath
而这个参数,其实就是 compileClasspath 的一个应用,如果你源文件引用了一个类,它的 jar 包不在 compileClasspath 中,那么在编译时 javac 就会报错找不到符号了
第二步:当源文件被编译成类文件后,Google 提供了 Transform 机制允许我们对二进制文件在打包前进行修改,比如前面图片中的 :app:transformClassesWithXXXForRelease SKIPPED
就是我们自定义的 Transform。通过 :app:transformClassesAndResourcesWithProguardForRelease SKIPPED
也可以看到 Proguard 也是通过 Transform 机制实现的,这里图片中一个 .class
文件,一个是 .jar/.class
文件,第一个显然是 javac
编译后的产物,第二个则是 runtimeClasspath
,就是那些需要被打包的二进制。相信大家这样就理解了 compileClasspath
和 runtimeClasspath
是如何影响打包过程
第三步:当 Transform 处理好所有的 class 文件后,接下来就是将 .class
文件转换为 .dex
文件。值得注意的是,javac 只能发现源码的问题,不会发现那些未参与编译的二进制的问题。而在 dex 转换过程中则可以发现比如类重复问题或者一个类,名字不变,但是由 Class 变成了 Interface 这类严重的代码问题。
第四步:就是将前面的和资源进行打包。对应的类是 PackageApplication
,得到这个 Task 后可以对打包的内容进行自定义
查看apk签名
- 法一:
使用JDK命令行工具查看,直接对比证书指纹。命令:keytool -printcert -v -file XXX.RSA
其中xxx.RSA
可通过:用压缩软件打开apk,找到META-INF
下的CERT.RSA
即可 - 法二:
用压缩软件打开apk,拷贝CERT.RSA
到本地,更改后缀后为CERT.p7b
,在windows上直接打开(选中“证书”,选择右侧证书文件,打开证书文件看详细信息)
查看签名文件keystore的SHA1、MD5
AS自带的debug.keystore
MAC的:
- cd到jdk的bin目录下
1
cd /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/bin
- 输入以下语句获取(密钥:android)
1
keytool -v -list -keystore /Users/xxx/.android/debug.keystore
- cd到jdk的bin目录下
Windows的:
- cd到jdk的bin目录下【有配置jdk环境变量的话这步可省略】
1
2
3cd C:\Program Files\Java\jdk1.7.0_79\bin
或者:
cd D:\dev\AS\jbr\bin - 输入以下语句获取(密钥:android)
1
keytool -v -list -keystore C:\Users\Administrator\.android\debug.keystore
- cd到jdk的bin目录下【有配置jdk环境变量的话这步可省略】
1 | keytool -list -v -keystore XXX.keystore |
上面的命令行以前可以看MD5,现在只有【SHA1、SHA256】
去掉冒号的js代码:【新版Chrome不让用了。那就直接用文本的全局替换】"CD:B0:3E:73:53:2B:C2:A2:54:5D:2E:75:67:74:BB:92".replace(/\:/g,"")
现在取MD5
【AS配置的jdk11
生成的签名文件】
- 法一:AS右侧
Gradle:Tasks>android>signingReport
,双击
【报Algorithm HmacPBESHA256 not available
,只更改AS的jdk为自带的jbr
路径(jdk17
)】 - 法二:单独取
md5
,使用腾讯工具【忘记包了】,有另外的apk:“MD5签名生成器”
【报Algorithm HmacPBESHA256 not available
,更改环境变量为AS的jbr
路径】
命令行生成数字签名文件
1 | keytool -genkey -alias demo.keystore -keyalg RSA -validity 40000 -keystore demo.keystore |
加固
apk 上架之前需要加固
乐固只有 exe,会把签名去掉,只有加固的功能- 360 加固宝【只勾选“签名校验”】,会把签名去掉,有加固
和重新签名的功能【只有每日一次免费加固,oppo、三星渠道不可用】 - oppo在线加固 【用基础版加固即可】
- 梆梆加固【加固比较慢,加固后的包也比较大】
- github加固工具
so加固
加壳步骤:
- 增加init函数:
cpp
文件添加void my_init(){}
Android.mk
文件添加:LOCAL_LDFLAGS += -WI,-init=my_init
- 将编译好的
so
拷贝到upx-3.96-win64
文件夹中 - 用命令行进入
upx-3.96-win64
目录中 - 输入命令:
upx --android-shlib 文件名称.so
- 加壳后的
so
会替换原有的so
签名、多渠道分包
packer:签名并多渠道分包
多渠道分包:packer-ng-plugin: 下一代Android打包工具(对Gradle 7.x的支持),对加固过未签名的apk进行多渠道分包
分包渠道信息
32位渠道【360加固后的包用它】
1 | 360 |
32位渠道【360加固的包以下平台报错,用梆梆加固】
1 | sanxing |
64位渠道
1 | meizu |
命令行签名【推荐用packer】
前提:要把
%JAVA_HOME%\bin
设置到环境变量jarsigner
【是v1】 命令可以(给加固后未签名的)重新签名
例:1
2
3
4
5#签名文件是 .keystore,注意不要带后缀
jarsigner -verbose -keystore /Users/用户名/mykeystore -signedjar ./signed.apk ./unsigned.apk haha
#签名文件是 .jks
jarsigner -verbose -keystore D:\mykey\my.jks -signedjar D:\mykey\signed.apk D:\mykey\aaa\myunsign.apk abc注意:证书名称即 Alias(你设置的别名);去掉 keystore 的扩展名称即可解决
“keystore No such file or directory”
问题;
注意:jarsigner
签名的是v1
。要v2
签名的话用apksigner
apksigner
【v2】1
apksigner sign --ks (签名地址) --ks-key-alias (别名) --out (签名后的apk地址) (待签名apk地址)
例子:
1
apksigner sign --ks D:\pack\597app.jks --ks-key-alias 597App --out "597Combine_jiagu_signed.apk" "597Combine_jiagu.apk"
上架
先注册,比较主流的应用市场
360手机助手
百度手机助手
豌豆荚
腾讯应用宝
联想乐商店
华为应用市场
荣耀
小米开放平台
vivo
百度
头条
三星应用商店
OPPO应用商店
魅族应用中心
努比亚
搜狗手机助手应用汇机锋市场乐视应用市场联通沃商店易用汇木蚂蚁优亿市场冒泡堂N多网锤子应用商店海信应用商店网易应用中心PC6安卓网准备的材料
APK文件、名称、版本号
APP的简介200字左右
一句话简介20字以内
软件截图4-5张
脱壳
AS library生成jar包和aar的方法总结
打包问题
:app:transformClassesAndResourcesWithR8ForRelease
问题:AS打包卡在app:transformClassesAndResourcesWithR8ForRelease
卡在app:transformClassesAndResourcesWithR8ForRelease
很长时间一直不能生成包,有时候产生java.lang.OutOfMemoryError: GC overhead limit exceeded
错误。而且编译打包时偶尔会报Error:java.lang.OutOfMemoryError
解决(在 gradle.properties
中添加):
1 | # 编译时使用守护进程 |
运行时报警告:
1 | WARNING: The following project options are deprecated and have been removed: |
解决方案:
移除gradle.properties
中android.enableAapt2=true