1. 根据资源文件和 AndroidManifest.xml 生成 R.java 文件 2. 处理 aidl,生成对应的 java文件,如果没有 aidl,则跳过 3. 编译工程源码(主项目,库)src 目录下所有的源码,同时上边生成的R.java和aidl生成的java文件也会被编译生成相应的 class 文件 4. 将第3步生成的class文件打包生成 .dex 文件 5. 将资源文件打包,生成初始的apk 6. 将第 4 步生成的 .dex 文件加入到apk中生成未签名的包 7. apk 签名
命令build-tools/安卓某个版本/aapt.exe package
set path=%path%;D:\Android\android-sdk\build-tools\25.0.2
aapt package -f -m -M AndroidManifest.xml -I D:/Android/android-sdk/platforms/android-22/android.jar -S res -J gen
参数的含义如下: -f : 如果编译出来的文件已经存在,强制覆盖 -m : 使得生成的包的目录放在 -J 参数指定的目录 -M : <AndroidManifest.xml目录> -I : 某个版本平台的android.jar的路径 -S : res文件夹路径 resource-sources -J : R.java的输出目录
没有则可以忽略
javac -encoding UTF-8 -source 1.6 -target 1.6 -bootclasspath D:/Android/android-sdk/platforms/android-22/android.jar -sourcepath src -classpath .;libs/android-support-v4.jar;libs/SDMCommon-2.2.3.jar;libs/AnySignV2.0.0.Android.1.1.1.jar;libs/bjca_anysign_tool.jar;libs/DataVaultLib.jar;libs/httpmime-4.1.3.jar;libs/SDMConnectivity-2.2.3.jar;libs/SDMParser-2.2.3.jar;libs/SMPRestClient-2.2.3.jar;libs/sup-client-util.jar;libs/wsecx-android_package-v1.4.jar;libs/xstream-1.4.4.jar -d bin/classes gen/com/nci/insprotection/*.java src/com/nci/insprotection/*.java
1.8.0_91
, 但我知道目标安卓5.1是基于JDK1.6, 所以指定-source
和-target
都是1.6-bootclasspath
覆盖引导类文件的位置, 我设置的编译版本是22-sourcepath
指定用以查找类或接口定义的源代码路径, 这是非常重要的一个小技巧, 填写src
后从而不用列举出com.nci.insprotection
下所有的包了-classpath/-cp
标签需要列举出所用用到的jar包.;libs/android-support-v4.jar;xxx.jar;yyy.jar
, 不能使用通配符, 否则会找不到符号。还要注意jar包的命名最好不带空格,否则得双引号引起来-d
指定放置生成的类文件的位置gen/com/nci/insprotection/*.java src/com/nci/insprotection/*.java
注意:
-d
文件夹必须存在, 否则会javac: 找不到目录: bin/classes
, 所以的手动mkdir符号: 类 BuildConfig
, 由于我是从Eclipse拷出的项目, 手动copy一个到gen
下R.java
的同级目录即可./** Automatically generated file. DO NOT MODIFY */
package com.nci.insprotection;
public final class BuildConfig {
public final static boolean DEBUG = true;
}
classes.dex
;命令build-tools/安卓某个版本/dx.bat
dx --dex --output=bin/classes.dex bin/classes libs/android-support-v4.jar libs/SDMCommon-2.2.3.jar libs/AnySignV2.0.0.Android.1.1.1.jar libs/bjca_anysign_tool.jar libs/DataVaultLib.jar libs/httpmime-4.1.3.jar libs/SDMConnectivity-2.2.3.jar libs/SDMParser-2.2.3.jar libs/SMPRestClient-2.2.3.jar libs/sup-client-util.jar libs/wsecx-android_package-v1.4.jar libs/xstream-1.4.4.jar
ERROR: No suitable Java found.
, 是因为我的JAVA_HOME
设置在了用户变量, 而非系统变量, 看来以后得用系统变量才靠谱aapt package -f -M AndroidManifest.xml -I D:/Android/android-sdk/platforms/android-22/android.jar -A assets -S res -F bin/res.zip
老版本可以用apkbuild.bat的命令apkbuilder bin/unsigned.apk -v -u -z bin/res.zip -f bin/classes.dex
但是如果如果被移除的话, 可以在安卓sdk安装目录tools\lib下是否存在sdklib.jar, 如果存在还是可以打包的.
set classpath=%path%;D:\Android\android-sdk\tools\lib\sdklib.jar
java com.android.sdklib.build.ApkBuilderMain bin/unsigned.apk -u -z bin/res.zip -f bin/classes.dex -rf src -rj libs -nf libs
java com.android.sdklib.build.ApkBuilderMain bin/aaa.apk -u -z bin/resources.ap_ -f bin/classes.dex -rf src -rj libs -nf libs
参数含义: 第一个参数是存放打包后的文件完整路径
src
, Followed by the path to a source folder. Adds the java resources found in that folder to the application package, while keeping their path relative to the source folder./libs
, Followed by the path to a jar file or a folder containing jar files. Adds the java resources found in the jar file(s) to the application package./libs
, 将主项目libs下面的so库打包 Followed by the root folder containing native libraries to include in the application package.jarsigner -verbose -keystore C:\Users\hp\Desktop\保全_其他文档\密钥\android.keystore -storepass android -keypass android -signedjar bin/signed.apk bin/unsigned.apk androiddebugkey
参数含义:
zipalign可以使用 4 字节对齐的方式优化我们签名打包后的 apk 文件中的以二进制格式存放的文件(如资源图片),这样的话,当资源文件被映射到内存时,应用程序访问资源文件的速率就会被大大提升,同时节省应用占用的内存空间。
检测有没有4字节对齐
set path=%path%;D:\Android\android-sdk\build-tools\27.0.3
zipalign -c -v 4 bin/signed.apk
优化命令
zipalign -f -v 4 bin/signed.apk bin/signed_aligned.apk
然后通过了验证Verification succesful。
这篇文章只是说明了一个通用的流程, 很多方面的优化还没有考虑, 比如资源压缩, 代码混淆, 很多地方都是从网上找的, 所以还是不建议这么做, 用 AS 的 gradle构建再发到应用市场才靠谱, 但是自己折腾还是有实验价值的。