身為一個Android工程師,你是否有考慮過一個Android項目工程如何經過編譯壓縮變成一個APK的呢?
你又是否編寫過打包工具完成多渠道打包呢?
下面我們來解密如何完成一個APK的打包。
1、使用Android SDK提供的aapt.exe生成R.java類文件
2、使用Android SDK提供的aidl.exe把.aidl轉成.java文件(如果沒有aidl,則跳過這一步)
3、使用JDK提供的javac.exe編譯.java類文件生成class文件
4、使用Android SDK提供的dx.bat命令行腳本生成classes.dex文件
5、使用Android SDK提供的aapt.exe生成資源包文件(包括res、assets、androidmanifest.xml等)
6、使用Android SDK提供的apkbuilder.bat生成未簽名的apk安裝文件
7、使用jdk的jarsigner.exe對未簽名的包進行apk簽名
完成一次APK打包一共有7步。從功能上來分,可以分成四步。
然后我們再來看下分別對應的命令行
使用aapt命令編譯資源文件 aapt package -f -m -J /home/tonywang/javaDemo/gen -S res -I /home/tonywang/sdk/platforms/android-23/android.jar -M AndroidManifest.xml
其中 -f -m -J /home/tonywang/javaDemo/gen
代表按覆蓋的形式在gen目錄下生成帶包路徑的R.java,-S res指定資源文件 ,-I
/home/tonywang/sdk/platforms/android-23/android.jar 指定使用的android類,-M AndroidManifest.xml指定程序的配置文件
使用javac命令編譯源文件 javac -target 1.7 -bootclasspath
/home/tonywang/sdk/platforms/android-23/android.jar -d bin
/home/tonywang/javaDemo/gen/com/tony/demo/*.java
/home/tonywang/javaDemo/src/com/tony/demo/*.java
-target:表示編譯之后的class文件運行的環(huán)境版本
-bootclasspath:表示編譯需要用到的系統(tǒng)庫
-d:表示編譯之后的class文件存放的目錄 這里需要把gen下和src下面的java都編譯了。
然后還有一個問題就是如果java文件存在多個包名下,就需要一個個列出來,很是麻煩。這里我寫了個shell腳本,把所有java名字都存在一個文本里,然后編譯對應的文件名列表就好了。腳本貼在下面
然后使用這條命令
javac -target 1.7 -bootclasspath /home/tonywang/sdk/platforms/android-23/android.jar -d bin @names.txt
使用dx命令,將class文件轉化成dex
dx –dex –output=/home/tonywang/javaDemo/bin/classes.dex /home/tonywang/javaDemo/bin/
使用aapt命令生成資源包文件(編碼AndroidManifest.xml,resource.arsc等)
aapt package -f -A assets -S res -I /home/tonywang/sdk/platforms/android-23/android.jar -M AndroidManifest.xml -F /home/tonywang/javaDemo/bin/javaDemo
使用apkbuilder命令來編譯
apk apkbuilder /home/tonywang/javaDemo/bin/javaDemo_unsigned.apk -v -u -z
/home/tonywang/javaDemo/bin/javaDemo -f
/home/tonywang/javaDemo/bin/javaDemo/classes.dex -rf
/home/tonywang/javaDemo/src
使用keytool來產生一個keystore文件
keytool -genkey -alias demo_test -keyalg RSA -validity 20000 -keystore demo.keystore
使用jarsigner簽名apk文件
jarsigner -keystore /home/tonywang/javaDemo/demo.keystore -storepass 123456 -keypass
123456 -signedjar /home/tonywang/javaDemo/bin/javaDemo_signed.apk
/home/tonywang/javaDemo/bin/javaDemo_unsigned.apk
至此,我們就完成了一次APK的編譯。
如果你需要多個渠道打包,可以編寫一個Ant腳本,或者gradle腳本。
PS.以上所有命令都基于Linux系統(tǒng)
附上查找所有java文件的腳本
findJava.sh:
function findjava (){ //友情提示,這里不是單引號,是反引號。Esc鍵下面那個按鍵 //表示shell執(zhí)行命令 for file int `ls $1` do if[ -d $1"/"$file ]; then findjava $1"/"$file else echo $1"/"$file >> /home/tonywang/javafile.txt fi done}dir='/home/tonywang/javaDemo/src'findjava $dir