aapt: android application package tool,SDK
(Android打包流程圖)
#Android打包流程
1.通過(guò)aapt工具將 資源文件(res)、清單文件(AndroidManifest.xml)生成對(duì)應(yīng)的R.java文件
* 在項(xiàng)目的根目錄下新建 gen目錄,并且依次在gen目錄下新建清單文件總包名對(duì)應(yīng)的文件目錄
> 例如: 清單文件中包名是org.zdc.android,那么就在gen目錄中新建目錄結(jié)構(gòu)為
> gen/org/zdc/android
* 通過(guò)命令生成R.java
aapt package -f -m -J [gen目錄](méi) -S [res目錄](méi) -I [android.jar目錄](méi) -M [AndroidManifest.xml目錄](méi)
2. 通過(guò)aidl工具 將 aidl文件轉(zhuǎn)化為java文件
aidl -I[src目錄](méi) -p[aidl框架環(huán)境文件(framework.aidl)] -o[aidl輸出目錄(gen)] [要轉(zhuǎn)換的aidl文件(your.aidl)]
3. 通過(guò)javac工具,將*.java文件轉(zhuǎn)化為*.class文件
javac -encoding [編碼] -target [版本(1.6 or 1.7)] -bootclasspath [android.jar] -cp [依賴的jar(多個(gè)用;隔開(kāi);結(jié)尾)] -d [class文件輸出目錄](méi) [要編譯的java文件(多個(gè)用空格分開(kāi))]
4. 將libs下的jar解壓到輸出目錄中
jar xvf [jar文件]
5. 通過(guò)dex命令 將class文件轉(zhuǎn)換為dex文件
dx.bat --dex --output=[全路徑的輸出文件(classes.dex)] [全路徑的class文件對(duì)應(yīng)的目錄](méi)
> [全路徑的class文件對(duì)應(yīng)的目錄](méi) : 如果此目錄依賴了其他的jar文件,需要用 `|`分隔開(kāi)
> 命令: dex.bat --dex --output=輸出路徑 需要轉(zhuǎn)換的class文件對(duì)應(yīng)的路徑
6. 通過(guò)aapt工具生成資源文件包
aapt package -f -M [清單文件(AndroidManifest.xml)] -S [資源文件目錄(res)] -A [資產(chǎn)文件目錄(assets)] -I [android環(huán)境jar(android.jar)] -F [輸出的文件(resoures.ap_)]
7. 生成未簽名的apk安裝文件
apkbuilder [apk輸出路徑] -u -z [打包好的資源文件全路徑] -f [全路徑dex文件] -rf [src全路徑] -rj [全路徑的libs目錄](méi)
8. 生成簽名的apk安裝文件
* 生成簽名文件
keytool -genkeypair -alias zdc -keyalg RSA -validity 3650 -keypass 123456 -storepass 123456 -keystore zdc.keystore
> -alias : 簽名的別名
> -validity : 簽名的時(shí)效
> -keyalg : 加密的算法,一般都用RSA
> -keystore : 生成的簽名路徑
> -keypass : 密鑰庫(kù)的密碼
> -storepass :密鑰的密碼
* 通過(guò)簽名文件給apk文件進(jìn)行簽名
jarsigner -keystore 簽名文件 -keypass 簽名密碼 -storepass 簽名文件的密碼 -signedjar 生成的簽名文件 未簽名的文件 簽名的別名
# 命令詳解
* package 命令: 打包編譯android資源
aapt p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \
[-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \
[--min-sdk-version VAL] [--target-sdk-version VAL] \
[--max-sdk-version VAL] [--app-version VAL] \
[--app-version-name TEXT] [--custom-package VAL] \
[-I base-package [-I base-package ...]] \
[-A asset-source-dir] [-G class-list-file] [-P public-definitions-file] \
[-S resource-sources [-S resource-sources ...]] [-F apk-file] [-J R-file-dir] \
[raw-files-dir [raw-files-dir] ...]
> []的參數(shù)都是可選參數(shù)。
> __[-d]: 指定一個(gè)或多個(gè)設(shè)備的資源文件被添加,多個(gè)資源文件用逗號(hào)隔開(kāi)__
> __[-f]: 是否覆蓋已經(jīng)存在的文件(添加此參數(shù)即為覆蓋,否則不覆蓋)__
> __[-m]: 打包資源的文件目錄,目錄地址是`-J`參數(shù)指定__
> __[-J]: 知道R文件生成的目錄__
> __[-S]: 需要打包的資源文件目錄__
> __[-I]: 指定環(huán)境android.jar的文件目錄__
> __[-M]: 清單文件的路徑__
#指令打包之R文件生成
1、API文檔路徑:
develop -> tools -> buid system(打包系統(tǒng),主要介紹打包的原理過(guò)程) -> 查看流程圖
2、AAPT:Android Application Package Tool android應(yīng)用打包工具
路徑:sdk -> buildtools – 版本 -> aapt
操作步驟:
①配置java環(huán)境,建議使用JDK1.6,因?yàn)镴DK1.7/1.8對(duì)指令操作有缺陷。
②拷貝工程到CMD文件夾(自己創(chuàng)建),刪除工程中自動(dòng)生成的目錄和文件(.setting、bin、gen、.classpath、.project)。
3、使用指令進(jìn)行操作
①在當(dāng)前工程根目錄下中創(chuàng)建gen目錄,在gen目錄下根據(jù)工程包名創(chuàng)建不同的目錄。
②CMD指令進(jìn)入到當(dāng)前工程的目錄下
③執(zhí)行命令
aapt package -f -m -J gen -S res -I ...\sdk\platforms\android-16\android.jar -M AndroidManifest.xml
#.aidl轉(zhuǎn)java文件
1、工具指令路徑:sdk -> platform-tools -> aidl.exe
2、framework.aidl路徑:sdk -> platforms -> android-14 –>framework.aidl
3、使用指令
aidl -Isrc -pD:\...\sdk\platforms\android-16\framework.aidl -ogen 項(xiàng)目路徑\src\aidl目錄\ITelephony.aidl
注意:有的aidl不會(huì)產(chǎn)生java文件
#指令打包之java轉(zhuǎn)class
1、Application source code:應(yīng)用源碼,指的就是我們工程中.java文件,比如src下的文件等等。
2、Java Compiler:java編譯器,R.java、Application source code和java InterFaces是通過(guò)java編譯器編譯成.class文件的
3、操作指令:
①在工程的根目錄下創(chuàng)建bin目錄,在bin目錄中classes目錄
②使用指令進(jìn)行操作
javac -encoding utf-8 -bootclasspath D:\...\sdk\platforms\android-16\android.jar -cp libs\android-support-v4.jar; -d bin\classes .\gen\cn\zdc\packagedemo\R.java
4、解壓jar包
因?yàn)閖ar包或者庫(kù)文件也在我們工程中的,所以在轉(zhuǎn)化的時(shí)候需要將jar包或者庫(kù)文件中的class文件一起轉(zhuǎn)化成dex
①進(jìn)入到bin目錄下的classes目錄下
②使用指令(兩個(gè)依次使用)
jar xvf ..\..\libs\nineoldandroids-2.4.0.jar
#指令打包之class轉(zhuǎn)dex
1、將class文件轉(zhuǎn)化成dex文件
①使用指令進(jìn)入到工程的bin目錄下的classes目錄中
②使用指令
dx --dex --output=項(xiàng)目路徑\bin\classes.dex 項(xiàng)目路徑\bin\classes
#指令打包之生成未簽名的apk
1、打包Apk需要三個(gè)元素
①編譯后的資源文件
②dex文件
③其他資源
2、操作步驟:
①得到編譯后的資源文件,使用指令
aapt package -f -M AndroidManifest.xml -S res -A assets -I D:\...\sdk\platforms\android-16\android.jar -F bin\resources.ap_
②使用dex和.ap_資源打包Apk
需要使用apkbuilder工具,路徑:sdk\tools\apkbuilder.bat
指令:
apkbuilder 項(xiàng)目路徑\bin\mobliesafe.apk -u -z 項(xiàng)目路徑\bin\resources.ap_ -f 項(xiàng)目路徑\bin\classes.dex -rf 項(xiàng)目路徑\src -rj 項(xiàng)目路徑\libs
3.注意:這個(gè)打包的apk是不能安裝的,因?yàn)閍ndroid系統(tǒng)安裝apk需要知道apk的簽名
#指令打包之生成簽名的apk
打包一個(gè)簽名的apk需要兩步操作
1.生成簽名文件
2.根據(jù)簽名文件進(jìn)行打包的apk
操作步驟:
1.生成簽名文件
①指令工具路徑:Java -> jdk -> bin -> keytool.exe
②使用指令進(jìn)入到工程的根目錄下
③使用指令
keytool -genkeypair -alias zdc -keyalg RSA -validity 3650 -keypass 123456 -storepass 123456 -keystore zdc.keystore
2.根據(jù)簽名文件進(jìn)行打包的apk
①指令工具路徑:Java -> jdk -> bin -> jarsigner.exe
②使用指令
jarsigner -keystore zdc.keystore -keypass 123456 -storepass 123456 -signedjar bin\mobliesafe_signed.apk bin\mobliesafe.apk zdc
#ant介紹
1.環(huán)境變量配置
ANT_HOME ....\apache-ant-1.9.6-bin
Path %ANT_HOME%\bin
2.校驗(yàn)
ant -help 或者 ant -version
#ant基本操作
1.腳本必須寫(xiě)在build.xml中
2.常用標(biāo)簽
project根標(biāo)簽 name: 項(xiàng)目名稱。必填 baseDir: 指定當(dāng)前目錄。(選填) default: 默認(rèn)執(zhí)行的任務(wù)。 (選填)Target任務(wù)標(biāo)簽 name: 任務(wù)名稱。必填echo輸出打印標(biāo)簽message:指定打印的內(nèi)容示例:<?xml version="1.0" encoding="utf-8"?><project name="test01"> <target name="helloworld"> <echo message="Hello World"></echo> </target></project>
3.執(zhí)行ant
①cmd -> ant : 查看build.xml文件是否構(gòu)建成功
②cmd -> ant helloworld : 執(zhí)行相應(yīng)的任務(wù)
4.如果不想通過(guò)ant helloworld執(zhí)行任務(wù),也可以設(shè)置project的default標(biāo)簽設(shè)置默認(rèn)執(zhí)行任務(wù)
示例:<project name="test01" default="helloworld"> <target name="helloworld"> <echo message="Hello World"></echo> </target></project>
4.也可以輸出引用
示例:<project name="test01" default="helloworld"> <target name="helloworld"> <echo message="Hello World"></echo> <echo message="${basedir}"></echo> </target></project>
${名稱}:引用;${basedir} : 本地路徑引用
5.執(zhí)行多個(gè)任務(wù)
5.1.兩個(gè)任務(wù)
示例:<project name="test01" default="helloworld"> <target name="helloworld"> <echo message="Hello World"></echo> </target> <target name="printdir" depends="helloworld"> <echo message="${basedir}"></echo> </target></project>
depends:和哪個(gè)任務(wù)關(guān)聯(lián),運(yùn)行先執(zhí)行depends中的任務(wù),再執(zhí)行當(dāng)前任務(wù)
運(yùn)行Cmd -> ant printdir,這時(shí)候就會(huì)先打印第一個(gè)任務(wù),在打印第二個(gè)任務(wù)
5.2.三個(gè)任務(wù)
示例:<project name="test01" default="helloworld"> <target name="helloworld"> <echo message="Hello World"></echo> </target> <target name="printdir" depends="helloworld"> <echo message="${basedir}"></echo> </target> <target name="helloAndroid" depends="helloworld,printdir"> <echo message="helloAndroid"></echo> </target></project>
多個(gè)任務(wù)depends中使用“,”分隔
#ant的文件操作
1.添加文件
示例:<project name="test02"> <target name="mkdir"> <mkdir dir="hehe"></mkdir> </target></project>
mkdir:表示創(chuàng)建目錄,dir:是目錄的名稱
2.刪除目錄
示例:<project name="test02"> <target name="deldir"> <delete dir="hehe"></delete> </target></project>
delete:刪除目錄,dir:目錄的名稱
3.創(chuàng)建文件
因?yàn)閯?chuàng)建出來(lái)文件還需要編輯,ant沒(méi)有這么強(qiáng)大,所以不能創(chuàng)建文件
4.刪除文件
創(chuàng)建文件test.txt示例:<project name="test02"> <target name="delfile"> <delete file="test.txt"></delete> </target></project>file:文件的名稱
#ant執(zhí)行javac指令
1.創(chuàng)建java文件
2.使用ant執(zhí)行編譯指令
原先:編譯:javac Test.java執(zhí)行java Test
示例:
<project name="test03"> <target name="javac"> <javac> <src path="."/> <exclude name="Test.java"/> <exclude name="Test1.java"/> </javac> </target></project>
javac:標(biāo)示javac指令,src:根目錄,exclude:表示不編譯哪個(gè)文件
#ant打包手機(jī)衛(wèi)士
在eclipse的手機(jī)衛(wèi)士的項(xiàng)目根目錄中新建文件build.xml,發(fā)現(xiàn)無(wú)法進(jìn)行快捷提示,這是因?yàn)槿鄙賏nt.dtd系統(tǒng)文件,將ant.dtd導(dǎo)入到工程的根目錄下在,在重新創(chuàng)建build.xml,創(chuàng)建的時(shí)候點(diǎn)擊下一步,不要直接點(diǎn)擊完成,在跳轉(zhuǎn)的下一個(gè)界面中選擇導(dǎo)入自己的dtd文件,完成即可
1.生成R文件
1.1.創(chuàng)建存放R文件的目錄,工程 -> build
1.2.創(chuàng)建gen目錄
示例:
<!-- 創(chuàng)建R文件存放的目錄 --><target name="init"> <!-- 當(dāng)下次調(diào)用的時(shí)候,要將文件目錄刪除,重新創(chuàng)建 --> <delete dir="${builddir}"></delete> <!-- 創(chuàng)建build\gen --> <mkdir dir="${gendir}"/></target>
路徑下面還會(huì)用,抽取路徑
<property name="builddir" location="${basedir}/build"/><property name="gendir" location="${builddir}/gen" />
property : 設(shè)置屬性
2.運(yùn)行
window -> show view -> ant -> 點(diǎn)擊加號(hào)將build.xml添加到ant中,如果出現(xiàn)錯(cuò)誤將build.xml中的<!DOCTYPE pro ject SYSTEM "ant.dtd" >注釋調(diào)用,點(diǎn)擊運(yùn)行即可
3.生成R文件
3.1.生成R文件需要aapt,但是aapt是在sdk目錄下的,如何去獲取呢?可以通過(guò)環(huán)境變量獲取
示例:<property environment="env"/><property name="sdkhome" location="${env.SDK_HOME}"/><property name="aapt" location="${sdkhome}/build-tools/19.1.0/aapt.exe"/>environment : 表示設(shè)置環(huán)境變量的標(biāo)示
3.2.生成R文件
示例:
<!-- 創(chuàng)建R文件思路: 1.找到aapt2.運(yùn)行aapt指令:aapt package -f -m -J gen -S res -I d:\...\sdk\platforms\android-14\android.jar -M AndroidManifest.xml--><target name="genR" depends="init"> <exec executable="${aapt}"> <arg value="package"></arg> <arg value="-f"></arg> <arg value="-m"></arg> <arg value="-J"></arg> <arg value="${gendir}"></arg> <arg value="-S"></arg> <arg value="${resdir}"></arg> <arg value="-I"></arg> <arg value="${androidjar}"></arg> <arg value="-M"></arg> <arg value="${manifest}"></arg> </exec></target>
exec : 執(zhí)行指令 executable:執(zhí)行什么指令,ant無(wú)法通過(guò)快捷提示出來(lái)的。
3.3.在執(zhí)行的時(shí)候還需要?jiǎng)?chuàng)建保存目錄
示例:
<!-- 創(chuàng)建R文件2:設(shè)置各種目錄 --><!-- res --><property name="resdir" location="${basedir}/res"></property><!-- android.jar --><property name="androidjar" location="${sdkhome}/platforms/android-14/android.jar"></property><!-- AndroidManifest.xml --><property name="manifest" location="${basedir}/AndroidManifest.xml"></property>
4.aidl轉(zhuǎn)化java文件操作:
4.1.設(shè)置屬性獲取aidl工具
示例:
<property name="aidl" location="${sdkhome}/build-tools/19.1.0/aidl.exe"></property>
4.2.執(zhí)行指令
因?yàn)橛卸鄠(gè)aidl文件所以需要執(zhí)行多個(gè)aidl指令,在ant中exec標(biāo)簽是執(zhí)行一條指令,apply標(biāo)簽執(zhí)行多條指令
示例:
<target name="aidltojava" depends="mkR"> <apply executable="${aidl}"> <arg value="-I${srcdir}"/> <arg value="-p${frameworkaidl}"/> <arg value="-o${gendir}"/> <fileset dir="${srcdir}" includes="**/*.aidl"/> </apply></target>
fileset : 執(zhí)行的文件的組,dir:文件存放的根目錄 includes:文件的位置
**/*.aidl : **/:表示:aidl文件的上級(jí)目錄 *.aidl:任何aidl文件
4.3.將相應(yīng)的目錄生成一下
示例:
<property name="srcdir" location="${basedir}/src"></property><!-- framwork.aidl --><property name="frameworkaidl" location="${sdkhome}/platforms/android-14/framework.aidl"></property>
5.java轉(zhuǎn)class操作
5.1.創(chuàng)建classes目錄,修改init任務(wù)
示例:
<target name="init"> <delete dir="${builddir}"></delete> <mkdir dir="${gendir}"/> <mkdir dir="${classesdir}"></mkdir></target>
5.2.設(shè)置轉(zhuǎn)化操作
示例:
<target name="javattoclass" depends="aidltojava"> <javac encoding="utf-8" bootclasspath="${androidjar}" destdir="${classesdir}"> <classpath> <fileset dir="${lisbsdir}" includes="**/*.jar"></fileset> </classpath> <src path="${srcdir}"></src> <src path="${gendir}"></src> </javac></target>
classpath : 表示設(shè)置路徑組,fileset:標(biāo)示多個(gè)文件
5.3.設(shè)置路徑屬性
示例:
<property name="lisbsdir" location="${basedir}/libs"></property><property name="classesdir" location="${builddir}/classes"></property>
6.解壓jar包
示例:
<target name="unjar" depends="javattoclass"> <unjar dest="${classesdir}"> <fileset dir="${lisbsdir}" includes="**/*.jar"></fileset> </unjar></target>
7.class文件轉(zhuǎn)dex文件
7.1.獲取dx工具
示例:
<property name="dx" location="${sdkhome}/platform-tools/dx.bat"></property>
7.2.設(shè)置執(zhí)行任務(wù)
示例:
<target name="classtodex" depends="unjar"> <exec executable="${dx}"> <arg value="--dex"></arg> <arg value="--output=${classesdex}"></arg> <arg value="${classesdir}"></arg> </exec></target>
7.3.設(shè)置路徑
示例:
<property name="classesdex" location="${builddir}/classes.dex"></property>
8.打包資源文件
8.1.設(shè)置執(zhí)行任務(wù)
示例:
<target name="restoresources" depends="classtodex"> <exec executable="${aapt}"> <arg value="package"></arg> <arg value="-f"></arg> <arg value="-M"></arg> <arg value="${manifest}"></arg> <arg value="-S"></arg> <arg value="${resdir}"></arg> <arg value="-A"></arg> <arg value="${assetsdir}"></arg> <arg value="-I"></arg> <arg value="${androidjar}"></arg> <arg value="-F"></arg> <arg value="${resourcesap}"></arg> </exec></target>
8.2.設(shè)置路徑
示例:
<property name="assetsdir" location="${basedir}/assets"></property><property name="resourcesap" location="${builddir}/resources.ap_"></property>
9.生成未簽名的apk
9.1.獲取打包指令
示例:
<property name="apkbuilder" location="${sdkhome}/tools/apkbuilder.bat"></property>
9.2.設(shè)置執(zhí)行任務(wù)
示例:
<target name="unsignedapk" depends="restoresources"> <exec executable="${apkbuilder}"> <arg value="${unsingedapk}"></arg> <arg value="-u"></arg> <arg value="-z"></arg> <arg value="${resourcesap}"></arg> <arg value="-f"></arg> <arg value="${classesdex}"></arg> <arg value="-rf"></arg> <arg value="${srcdir}"></arg> <arg value="-rj"></arg> <arg value="lisbsdir"></arg> </exec></target>
9.3.設(shè)置路徑
示例:
<property name="unsingedapk" location="${builddir}/mobliesafe_unsigned.apk"></property>
10.生成簽名的apk
將之前用命令寫(xiě)的key文件拷貝到工程的根目錄下
10.1.獲取執(zhí)行指令工具
示例:
<property name="javahome" location="${env.JAVA_HOME}"></property><property name="jarsigner" location="${javahome}/bin/jarsigner.exe"></property>
10.2.設(shè)置執(zhí)行任務(wù)
<target name="signedapk" depends="unsignedapk"> <exec executable="${jarsigner}"> <arg value="-keystore"></arg> <arg value="${keystore}"></arg> <arg value="-keypass"></arg> <arg value="123456"></arg> <arg value="-storepass"></arg> <arg value="123456"></arg> <arg value="-signedjar"></arg> <arg value="${signedpakdir}"></arg> <arg value="${unsingedapk}"></arg> <arg value="zdc85"></arg> </exec> </target>
10.3.設(shè)置路徑
示例:
<property name="keystore" location="${basedir}/zdc85.keystore"></property><property name="signedpakdir" location="${builddir}/mobliesafe_signed.apk"></property>
11.資源混淆
11.1.解壓AndResGuard-master.zip,在其中的tool_output找到AndResGuard-cli-1.1.4.jar
11.2.將AndResGuard-cli-1.1.4.jar拷貝到工程的tools目錄下
11.3.將config.xml文件拷貝到工程的tools目錄下
11.4.修改config.xml文件
示例:
<resproguard> <issue id="sign" isactive="true"> <!--the signature file path, in window use \, in linux use /, and the default path is the running location--> <path value="zdc85.keystore"/> <!--storepass--> <storepass value="123456"/> <!--keypass--> <keypass value="123456"/> <!--alias--> <alias value="zdc85"/> </issue> </resproguard>
11.5.使用指令測(cè)試,必須使用JDK1.7,并且路徑不能有空格
D:\java\jdk7\bin\java.exe -jar AndResGuard-cli-1.1.4.jar ..\build\mobliesafe_unsigned.apk
11.6.解決7za的錯(cuò)誤
將SevenZip\executable目錄下找到7za-windows_x86_64.exe拷貝到工程的tools目錄下
11.7.將key文件也放到目錄下重新執(zhí)行命令
D:\java\jdk7\bin\java.exe -jar AndResGuard-cli-1.1.4.jar ..\build\mobliesafe_unsigned.apk -7zip 7za-windows_x86_64.exe
11.8.設(shè)置ant執(zhí)行任務(wù)
設(shè)置JDK1.7路徑
示例:
<property name="java7" location="D://java/jdk7/bin/java.exe" /> 設(shè)置執(zhí)行任務(wù)示例:<target name="proguardResourceApk" depends="unsignedapk"> <exec executable="${java7}"> <arg value="-jar" /> <arg value="tools/AndResGuard-cli-1.1.4.jar" /> <arg value="${unsingedapk}" /> <arg value="-7zip" /> <arg value="tools/7za-windows_x86_64.exe" /> </exec></target>
注意:這時(shí)候需要將config.xml拷貝到根目錄下