幾個月前在一個項目的開發過程中,UI同學在製作Android Icon時遇到一個測試難題:每次想在手機上看效果總是很彆扭,要重新扔到工程裏面進去然後再用IDE build一次,費時間不說,IDE也很吃內存CPU。
我便想寫個批處理,希望能適當減少這一方面的成本,使用者只需要將三個尺寸(72*72, 48*48, 36*36)的ICON放置到根目錄下,然後運行批處理文件run.bat,即能生成android.apk安裝包。 想法很簡單,但是也耗了一些功夫才搞定。
Apk生成流程
大致可以分6步走
第一步 生成R.java資源文件
1
|
@aapt
package -f -m -J %ROOT%\gen -S %PATH_PROJECT%\res -I %PATH_SDK_PLATFORM%\android.jar -M %PATH_PROJECT%\AndroidManifest.xml |
這裏我們自動將資源文件res(-S)生成 R.java文件並存放到 gen目錄下(-m -J),當然我們還需要android.jar的API庫(-I)跟android的配置文件AndroidManifest.xml(-M)的協助,並且設置爲強制覆蓋不詢問形式(-f)
第二步 編譯java文件
1
|
@javac
-encoding GB18030 -target 1.6 -bootclasspath %PATH_SDK_PLATFORM%\android.jar -d %ROOT%\classes %PATH_PROJECT%\src\%PATH_PACKAGE%\*.java %ROOT%\gen\%PATH_PACKAGE%\R.java
|
生成class文件,我們需要藉助jdk來完成。將java文件與生成的資源ID文件R.java一起編譯成.class文件,並存放到classes目錄中(-d)。
第三步 打包.class文件
1
|
@call
dx --dex --output=%ROOT%\classes.dex %ROOT%\classes |
將編譯好的.class文件打包成classes.dex二進制執行文件。
第四步 打包資源文件
1
|
@aapt
package -f -M %PATH_PROJECT%\AndroidManifest.xml -S %PATH_PROJECT%\res -A %ROOT%\assets -I %PATH_SDK_PLATFORM%\android.jar -F %ROOT%\resources.ap_
|
選中AndroidManifest.xml (-M), 資源文件夾res(-S) 跟 assets(-A),加上Android的API庫(-I),一起打包輸出到resources.ap_ 文件中(-F)。
第五步 打包APK文件
1
|
@call
apkbuilder %ROOT%\unsigned.apk -u -z %ROOT%\resources.ap_ -f %ROOT%\classes.dex |
將資源文件包resources.ap_跟二進制文件包classes.dex一起打包成未簽名的apk壓縮包 unsign.apk。
第六步 簽名
1
|
@java
-jar %PATH_SIGN%\signapk.jar %PATH_SIGN%\testkey.x509.pem %PATH_SIGN%\testkey.pk8 unsigned.apk android.apk
|
這裏我們使用的是platform裏面兩個testkey,調用signapk.jar來執行,最終生成android.apk的簽名apk包,這時候就可以安裝到android系統中了。
目錄結構
1
2
3
4
5
6
7
8
9
10
11
12
13
|
+autoPackage
(根目錄) -+androidProject
(工程目錄) ---(一個普通的工程目錄,不贅述) -+platform
(Android.jar目錄) ---android.jar
(用了Android 2.2的platform) -+sign
(簽名文件目錄) ---signapk.jar
(在源碼\platform\build\tools\signapk目錄下) ---testkey.pk8
(在源碼\platform\build\target\product\security目錄下) ---testkey.x509.pem
(在源碼\platform\build\target\product\security目錄下) --run.bat
(批處理文件) --icon-36.png
(低分辨率ICON) --icon-48.png
(中分辨率ICON) --icon-72.png
(高分辨率ICON) |
對應需求、目錄及流程寫出批處理腳本 run.bat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@title
Auto package And Sign @echo
******************************* start ********************************* @set
ROOT=C:\autoPackage @set
PATH_PACKAGE=com\isfeel\autopackage @set
PATH_SDK_PLATFORM=%ROOT%\platform @set
PATH_SIGN=%ROOT%\sign @set
PATH_PROJECT=%ROOT%\androidProject @del
%ROOT%\android.apk @mkdir
bin gen classes assets @copy
/Y icon-72.png %PATH_PROJECT%\res\drawable-hdpi\icon.png @copy
/Y icon-48.png %PATH_PROJECT%\res\drawable-mdpi\icon.png @copy
/Y icon-36.png %PATH_PROJECT%\res\drawable-ldpi\icon.png @aapt
package -f -m -J %ROOT%\gen -S %PATH_PROJECT%\res -I %PATH_SDK_PLATFORM%\android.jar -M %PATH_PROJECT%\AndroidManifest.xml @javac
-encoding GB18030 -target 1.6 -bootclasspath %PATH_SDK_PLATFORM%\android.jar -d %ROOT%\classes %PATH_PROJECT%\src\%PATH_PACKAGE%\*.java %ROOT%\gen\%PATH_PACKAGE%\R.java @call
dx --dex --output=%ROOT%\classes.dex %ROOT%\classes @aapt
package -f -M %PATH_PROJECT%\AndroidManifest.xml -S %PATH_PROJECT%\res -A %ROOT%\assets -I %PATH_SDK_PLATFORM%\android.jar -F %ROOT%\resources.ap_ @call
apkbuilder %ROOT%\unsigned.apk -u -z %ROOT%\resources.ap_ -f %ROOT%\classes.dex @java
-jar %PATH_SIGN%\signapk.jar %PATH_SIGN%\testkey.x509.pem %PATH_SIGN%\testkey.pk8 unsigned.apk android.apk @del
%ROOT%\unsigned.apk %ROOT%\classes.dex %ROOT%\resources.ap_ @rmdir
/s/q %ROOT%\bin %ROOT%\gen %ROOT%\classes %ROOT%\assets @echo
*********************** finished success! ****************************** @pause @exit
|
我們此時可以查看下最終生成的apk包含什麼文件
1
|
aapt
l android.apk |
輸出
1
2
3
4
5
6
7
8
9
10
|
META-INF/MANIFEST.MF META-INF/CERT.SF META-INF/CERT.RSA AndroidManifest.xml classes.dex res/drawable-hdpi/icon.png res/drawable-ldpi/icon.png res/drawable-mdpi/icon.png res/layout/main.xml resources.arsc |
簡單介紹下aapt
aapt是Android Asset Packaging Tool的縮寫,是打包資源文件的工具,我們這裏主要用到aapt 的 package 參數也可以用來查看壓縮包(zip, jar, apk)的內容,如剛剛使用的
aapt l android.apk
列出了包的內部結構,另外我們比較常用的還有
1
|
aapt
d badging android.apk |
可以通過它來查看apk包的versionName、versionCode、permissions、label、icon、分辨率等等信息
1
|
aapt
d permissions android.apk |
比較專一,它只會告訴你apk包的packagename、permissions列表兩個信息
信息過多如
1
|
aapt
l -a android.apk |
輸出了apk包的所有信息,可以通過重定符 '>' 將信息輸出到文件中,如
1
|
aapt
l -a android.apk > android.txt |
具體其他參數可以通過
1
|
aapt
--help |
獲取參數對應的功能的信息,這裏就不一一解釋了。
對於linux下的開發來說,aapt的使用頻率還算蠻高的,至少Doyang認爲敲着命令行蠻爽的,裝B利器嘛,哈哈!
參考資料:
1.Android
Building and Running