純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第1张

打包系列教程目錄:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一)

用ant的build.xml構建自動化打包android apk 完全詳解(打包系列教程之二)

Android 多渠道打包之混淆文件ProGuard技術詳解-特別篇(打包系列教程之三)

android studio gradle 多渠道打包之完全詳解(打包系列教程之四)

android studio gradle 多版本多apk打包(打包系列教程之五)

詳解高速神器python腳步打包android apk,超級快!!(打包系列教程之六)


工作也有一段時間了,剛來到公司時,說起來慚愧,打包根本不怎么會,然后呢,各種原因,管理svn和打包的各類工作都必須要由我來做了,之前的工程師留下的ant打包工具的打包速度,我實在忍無可忍了!太慢了!一個包8分鍾,搞毛!沒辦法,自己只能去研究學習,研究了好多大牛的博客后,對打包的整體過程我也終於弄明白了,不容易啊!因此也想在這里分享給大家,為了大家能比較清晰的弄明白android打包的過程與方法,我決定從最簡單也最純手工的打包方式開始分析,一步一步記錄,方便大家理解,這個打包系列教程,我打算分3-4篇文章來說明,為什么?因為我要分析的不止一種打包方式,而是有3種,ant打包方式,gradle打包方式以及相當牛b的美團打包方式python打包!打包系列教程概要如下:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第2张

今天就以mac系統為例,來分享一下通過ant命令行對android app進行打包,其他3篇將后續給出,這里並非使用android 官方提供的ant工具。本篇內容概要如下

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第3张

一:搭建環境

1.先安裝ant工具,可以到ant官網:http://ant.apache.org/ 下載即可

2.配置ant環境變量(mac平台)

打開命令行:輸入 open .bash_profile 打開配置文件配置如下:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第4张

保存后,在命令行輸入 source .bash_profile 刷新一下配置文件,然后在命令行輸入 ant 回車 出現以下的結果則安裝成功!

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第5张

這里還需要用到android自帶的工具包,大家一定要提前配置好哈!

二:使用ant 命令行打包android應用程序

1.首先我們來了解一下android打包到底做了哪些事?

(1). 生成用於應用的R.java;
(2). 編譯所有java文件為class文件;
(3). 打包class文件和jar包為classes.dex;
(4). 打包assets和res資源為資源壓縮包(例如res.zip,名字可以自己定義);
(5). 組合classes.dex和res.zip生成未簽名的APK;
(6). 生成有簽名的APK;
(7). 對簽名包進行zipalign優化;

用一句話說就是先把java文件編譯成class文件,再將class文件和所依賴的jar打包成classes.dex文件,然后再打包aaset和res文件等資源文件resource.zip,再把dex和zip文件合並為未簽名apk,最后進行簽名,這就完成整個打包等過程。

那我們就一步一步來吧。

我們以Command4Ant為案例:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第6张

(1). 生成用於應用的R.java;

這里要使用android官方提供的aapt工具,生成R.java文件,這個工具存於/SDK/build-tools下,因此需要

配置好環境變量(配置方法同上)。

先cd到該項目根目錄下(別忘了哦),為了區分顯示執行結果(因為eclipse工程存在gen和bin目錄),我把存放R.java文件的目錄放在桌面的ant文件夾下的gen,同時在同級目錄創建bin目錄,用於存放classes.dex文件(后面使用)

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第7张

我mac上的路徑分別為:

/Users/zejian/Desktop/ant/gen

/Users/zejian/Desktop/ant/bin

mac上使用的android.jar 路徑為:

/Users/zejian/Documents/androidStudio_1.3/SDK/platforms/android-22/android.jar 

在命令行輸入如下命令:

aapt package -f -m -J /Users/zejian/Desktop/ant/gen -S res -M AndroidManifest.xml 
-I /Users/zejian/Documents/androidStudio_1.3/SDK/platforms/android-22/android.jar

參數含義如下:

-f 如果編譯生成的文件已經存在,強制覆蓋。

-m 使生成的包的目錄存放在-J參數指定的目錄

-J 指定生成的R.java 的輸出目錄路徑(存放在桌面的gen)

-S 指定res文件夾的路徑

-I 指定某個版本平台的android.jar文件的路徑(我使用的是API-22),

回車運行,在桌面ant/gen目錄下生成R.java文件:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第8张

(2). 編譯所有java文件為class文件(包括剛剛生成的R.java文件和src下的*.java文件);

我們將使用javac命令進行編譯(我使用的java版本是jdk1.7):

在命令行輸入:

javac -target 1.7 -bootclasspath /Users/zejian/Documents/androidStudio_1.3/SDK/platforms/android-22/android.jar -d /Users/zejian/Desktop/ant/bin src/com/example/command4ant/*.java /Users/zejian/Desktop/ant/gen/com/example/command4ant/R.java 

參數含義如下:

-target <jdk版本>               生成特定 jdk 版本的類文件

-bootclasspath <路徑>        覆蓋引導類文件的位置

-d <目錄>                    指定存放生成的類文件的位置

-sourcepath <路徑>           指定查找輸入源文件的位置(這里包含兩個地方一個是src,一個是桌面gen生成的R.java)

回車運行,在桌面bin目錄下生成如下文件:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第9张

(3). 打包class文件和jar包為classes.dex;

這個比較簡單,主要使用到android官方提供的構建工具dx 存在於/SDK/build-tools目錄下(記得配置該路徑的環境變量哈);

在命令行輸如下命令:

dx --dex --output=/Users/zejian/Desktop/ant/bin/classes.dex /Users/zejian/Desktop/ant/bin

--output=<要生成的classes.dex路徑>  <要處理的class文件的路徑>

這里我存放classes.dex文件的路徑跟要處理文件是一樣的。

回車運行,結果報錯:

一開始咋一看是:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第10张

根據網上的資料顯示這個是jar沖突造成的,但我沒用jar包啊,就一個v4包,刪了再運行還是報錯;后來往下看才發現:

原來是這個錯誤:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第11张

這其實是jdk版本兼容性問題。我引入的jar包編譯環境(比如是1.7)要高於android中默認的jdk編譯版本(我用的是1.6)。要解決這個問題,

也很簡單只要android項目的編譯jdk版本要高於等於引入jar包的編譯jdk版本,然后重新編譯就好了。既然如此修改eclipse的jdk編譯版本改為1.7即可:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第12张

重新執行第(2)步,再運行第(3)步,運行成功!生成classes.dex如下:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第13张

(4). 打包assets和res資源為資源壓縮包(例如res.zip,名字可以自定義);

這個還是要使用android官方提供的aapt工具,命令如下:

aapt package -f -M AndroidManifest.xml -S res -I /Users/zejian/Documents/androidStudio_1.3/SDK/platforms/android-22/android.jar -A assets -F /Users/zejian/Desktop/ant/bin/res.zip

參數含義:

-f 如果編譯生成的文件已經存在,強制覆蓋。

-m 使生成的包的目錄存放在-J參數指定的目錄

-S 指定res文件夾的路徑

-I 指定某個版本平台的android.jar文件的路徑

-A 指定assert文件夾的路徑

-F 指定輸出文件完整路徑

回車運行,如下生成res.zip文件:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第14张

(5). 組合classes.dex和res.zip生成未簽名的APK;

這里主要使用apkbuilder腳本,其實是個批處理文件,不過android 3.0后已經被刪除,但網上還是可以找到這個腳本的,

直接拷貝放到/SDK/tools下即可。其實里面執行的就是sdklib.jar。

apkbuilder /Users/zejian/Desktop/ant/bin/unsigned_command4Ant.apk -v -u -z /Users/zejian/Desktop/ant/bin/res.zip -f /Users/zejian/Desktop/ant/bin/classes.dex  

參數含義:

第一個參數是存放打包后的文件完整路徑

-v Verbose 顯示過程信息

-u 創建一個無簽名的包

-z 指定apk資源路徑

-f 指定dex文件路徑

回車運行,如下生成未簽名的apk

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第15张

(6). 生成有簽名的APK(debug4zj.keystore這里我提前准備好了);

直接存放在項目的根目錄下,下面直接執行簽名命令(jarsigner命令,java的簽名工具):

jarsigner -verbose -keystore debug4zj.keystore -storepass zejian -keypass zejian -signedjar /Users/zejian/Desktop/ant/bin/signed_command4Ant.apk /Users/zejian/Desktop/ant/bin/unsigned_command4Ant.apk debug4zj
最后的“別名”一定要保證正確,不然會報如下錯誤:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第16张

參數含義:

-verbose  簽名/驗證時輸出詳細信息

-keystore  密鑰庫路徑

-storepass  用於密鑰庫完整性的口令(密碼)

-keypass    專用密鑰的口令(密碼)

-signedjar   已簽名的 apk 文件的名稱 (第一個apk是簽名之后的文件, 第二個apk是需要簽名的文件)

運行結果如下:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第17张

生成apk如下:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第18张

(7). 對簽名包進行zipalign優化;

首先,我們先來搞清楚什么是zipalign,又為什么要進行zipalign優化?

我跑去google官網查詢了一下,發現google官網最新文檔是這樣解釋的:

zipalign is an archive alignment tool that provides important optimization to Android application (.apk) files. The purpose is to ensure that all uncompressed data starts with a particular alignment relative to the start of the file. Specifically, it causes all uncompressed data within the .apk, such as images or raw files, to be aligned on 4-byte boundaries. This allows all portions to be accessed directly with mmap() even if they contain binary data with alignment restrictions. The benefit is a reduction in the amount of RAM consumed when running the application.

This tool should always be used to align your .apk file before distributing it to end-users. The Android build tools can handle this for you. Android Studio automatically aligns your .apk after it signs it with your private key. The build scripts used when compiling your application with Gradle also align your .apk, as long as you have provided the path to your keystore and the key alias in your project gradle.properties file, so that the build tools can sign the package first.

Caution: zipalign must only be performed after the .apk file has been signed with your private key. If you perform zipalign before signing, then the signing procedure will undo the alignment. Also, do not make alterations to the aligned package. Alterations to the archive, such as renaming or deleting entries, will potentially disrupt the alignment of the modified entry and all later entries. And any files added to an "aligned" archive will not be aligned.

The adjustment is made by altering the size of the "extra" field in the zip Local File Header sections. Existing data in the "extra" fields may be altered by this process.

第一段話的意思是,zipalign是一種文檔對齊工具,主要用於優化android應用程序即apk,使用zipalign的主要目的是確保apk安裝包中所以未進行數據壓縮的文檔文件可以從一個特定的相對位置開始讀取。需要特別說明的是,它將會導致apk中所有未壓縮的數據,例如圖片資源,raw文件等被進行4字節對齊的優化。這將允許所有被分配的內存數據可以用mmap()直接訪問,即使這些數據包含二進制數據的限制。這樣做的益處是可以減少應用運行時所占用的內存大小。

簡單的說就是,zipalign可以使用4字節對齊的方式優化我們簽名打包后的apk文件中的以二進制格式存放的文件(如資源圖片),這樣的話,當資源文件被映射到內存時,應用程序訪問資源文件的速率就會被大大提升,同時節省應用占用的內存空間。為什么?我舉個簡單例子,比如我們准備去一個村里找八戶人家,分別給他們發禮包,恰好這八戶人家都不在同一個地方,如果我們一戶一戶的去找,是不是特別浪費時間?但如果我們去找村里的廣播員,讓廣播員向全村發廣播,某莫有禮品領取,請到廣場來集合,等他們都來了,我們再一次性發放,是不是更有效率?zipalign優化就是有點像廣播員,可以優化二進制數據,讓內存訪問更加高效。從而也更加節省內存空間。

第二段話主要是說我們使用android studio進行gradle簽名打包時,as會自動幫我們完成zipalign優化操作。

第三段話主要強調zipalign優化一定要在簽名后進行,如果在我們在簽名前,進行zipalign優化的話,當我們再次進行簽名時,zipalign優化將會被破壞,還要注意的是,在apk打包簽名並進行了zipalign優化后,盡量不要改變apk文件的任何屬性,比如改變名稱或者刪除文件,這都將有可能導致zipalign優化被破壞。

怎么使用呢?

我們可以使用以下命令進行zipalign優化檢測,如果沒進行過zipalign優化的apk將會認證失敗。

zipalign -c -v <alignment> existing.apk

-c 表示進行zipalign優化檢測

-v 輸出過程信息

現在我們就對剛才生成的apk包也就是signed_command4Ant.apk進行zipalign優化檢測,我們在命令行輸入如下信息:

zipalign -c -v 4 /Users/zejian/Desktop/ant/bin/signed_command4Ant.apk

4 這個數字表示檢測4個字節對齊的意思。

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第19张

從輸出結果可以知道,未進行zipalign優化的apk,認證失敗了!

那該怎么進行zipalign優化呢?可以使用如下語句

zipalign [-f] [-v] <alignment> infile.apk outfile.apk

-f  如果文件已經存在,強制覆蓋

-v 輸出詳細信息

- 需要zipalign優化的apk  優化后的apk名稱以及存放位置

接下來,我們就對signed_command4Ant.apk進行zipalign優化,我們在命令行輸入如下信息:

zipalign -v 4 /Users/zejian/Desktop/ant/bin/signed_command4Ant.apk /Users/zejian/Desktop/ant/bin/zipalign_signed_command4Ant.apk
輸出結果如下:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第20张

好了,zipalign優化完成,在桌面ant文件的bin下生成了經過zipalign優化的zipalign_signed_command4Ant.apk包:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第21张

我們再次對已經進行過zipalign優化的apk進行檢測,我們在命令行輸入如下信息:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第22张

好了,整個android apk打包已經完成。其實這里有少處理了aidl文件,因為項目中沒有,我也就沒演示了。

有需要的話,大家可以看一下這篇文章 http://blog.csdn.net/sodino/article/details/6419498

最后附上整個流程圖,供大家參考:

純ant命令行打包android apk之圖文從原理角度完全詳解android打包過程(打包系列教程之一) -开发者知识库,第23张

到此最簡單的ant打包流程就梳理完了。












最佳答案:

本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复