android程序自动化生成apk的过程

来源:互联网 发布:鱼缸淘宝网首页 编辑:程序博客网 时间:2024/05/16 23:40

在编写android的时候,写好java代码后,eclipse直接帮我们生成了可安装的apk,但有时需要自动化的去生成个性化apk的时候,我们就需要编写脚本或代码来自动生成一个apk,在生成apk之前必须了解下android编译apk的过程;

 

现在很多人想对Android工程的编译和打包进行自动化,比如建立每日构建系统、自动生成发布文件等等。这些都需要我们对Android工程的编译和打包有一个深入的理解,至少要知道它的每一步都做了什么,需要什么环境和工具,输入和输出是什么。那么我们就来挖掘一下Android的编译过程中的细节。

首先,我们假定你的系统(什么系统都行,不限于Linux还是Windows系统,当然,我在这里默认使用Linux系统来举例子,但在 Windows中几乎没有什么差别)已经安装了JDK和Android SDK。再假定你的Android SDK的路径是ANDROID_SDK_HOME,你想要编译的Android OS版本是ANDROID_OS_VERSION(比如android-1.6、android-8、android-10等)。

我们重点关心的是(1)这个过程的输入是什么?(2)这个过程的输出是什么?(3)这个过程使用了什么工具?至于使用什么参数,可以自己去看对应命令的帮助文件,或者在网上搜索,这不是本文的重点。

步骤中提到的工具如下表:

名称功能介绍在操作系统中的路径aaptAndroid资源打包工具${ANDROID_SDK_HOME}/platform-tools/apptaidlAndroid接口描述语言转化为.java文件的工具${ANDROID_SDK_HOME}/platform-tools/aidljavacJava Compiler${JDK_HOME}/javac或/usr/bin/javacdex转化.class文件为Davik VM能识别的.dex文件${ANDROID_SDK_HOME}/platform-tools/dxapkbuilder生成apk包${ANDROID_SDK_HOME}/tools/opkbuilderjarsigner.jar文件的签名工具${JDK_HOME}/jarsigner或/usr/bin/jarsignerzipalign字节码对齐工具${ANDROID_SDK_HOME}/tools/zipalign

第一步:打包资源文件,生成R.java文件
【输入】Resource文件(就是工程中res中的文件)、Assets文件(相当于另外一种资源,这种资源Android系统并不像对res中的文件那样优化它)、AndroidManifest.xml文件(包名就是从这里读取的,因为生成R.java文件需要包名)、Android基础类库(Android.jar文件)
【输出】打包好的资源(一般在Android工程的bin目录可以看到一个叫resources.ap_的文件就是它了)、R.java文件(在gen目录中,大家应该很熟悉了)
【工具】aapt工具,它的路径在${ANDROID_SDK_HOME}/platform-tools/aapt(如果你使用的是Windows系统,按惯例路径应该这样写:%ANDROID_SDK_HOME%\platform-tools\aapt.exe,下同)。

第二步:处理AIDL文件,生成对应的.java文件(当然,有很多工程没有用到AIDL,那这个过程就可以省了)
【输入】源码文件、aidl文件、framework.aidl文件
【输出】对应的.java文件
【工具】aidl工具

第三步:编译Java文件,生成对应的.class文件
【输入】源码文件(包括R.java和AIDL生成的.java文件)、库文件(.jar文件)
【输出】.class文件
【工具】javac工具

第四步:把.class文件转化成Davik VM支持的.dex文件
【输入】 .class文件(包括Aidl生成.class文件,R生成的.class文件,源文件生成的.class文件),库文件(.jar文件)
【输出】.dex文件
【工具】javac工具

第五步:打包生成未签名的.apk文件
【输入】打包后的资源文件、打包后类文件(.dex文件)、libs文件(包括.so文件,当然很多工程都没有这样的文件,如果你不使用C/C++开发的话)
【输出】未签名的.apk文件
【工具】apkbuilder工具

第六步:对未签名.apk文件进行签名
【输入】未签名的.apk文件
【输出】签名的.apk文件
【工具】jarsigner

第七步:对签名后的.apk文件进行对齐处理(不进行对齐处理是不能发布到Google Market的)
【输入】签名后的.apk文件
【输出】对齐后的.apk文件
【工具】zipalign工具

知道了这些细节之后,我们就可以实现很多我们想实现东西了,比如:自动化,我们可以使用某种脚本,像Windows下的批处理,linux下的Bash,Java下的Ant,Python、Perl这样的脚本语言,甚至直接用Java、.net这们的强类型语言也是可以的。如果你真正弄懂了上面的步骤,了解了编译打包过程的本质,你完全可以以你想要的任何方式实现它的自动化,这才是真正的“举一反三,以不变应万变”。再比如,对Android SDK的精简,大家知道,现在Android SDK动辙几百兆,我们完全可以应用上面的知识,只保留必要的工具,把SDK精简到10M以下。当然,还可以做很多事情,前提是你真正弄懂了它。

备注:android sdk版本不同,安装之后在tools下可能会少dx.bat,apkbuilder.bat文件,通过升级SDK或者单独下载放在对应的目录,也可正常使用;
一、手动编译APK的流程如下:


  1.生成资源文件:使用Android SDK提供的aapt.exe生成R.java类文件


  2.编译本地库:使用Android SDK提供的aidl.exe把.aidl转成.java文件(如果没有aidl,则跳过这一步)


  3.编译java代码:使用JDK提供的javac.exe编译.java类文件生成class文件


  4.生成dex文件:使用Android SDK提供的dx.bat命令行脚本生成classes.dex文件


  5.打包资源文件:使用Android SDK提供的aapt.exe生成资源包文件(包括res、assets、androidmanifest.xml等)


  6.生成apk文件:使用Android SDK提供的apkbuilder.bat生成未签名的apk安装文件


  7.对apk文件进行签名:使用jdk的jarsigner.exe对未签名的包进行apk签名


二、详细步骤


1)、准备工作


         A、安装好JDK,配置环境变量;


         B、将android-sdk-windows\platform-tools和 android-sdk-windows\tools 添加到CLASSPATH 环境变量中;


         C、打开CMD命令行界面,将当前目录切换到工程所在目录;


         D、准备一个目录,以下例子是以在eclipse中创建的Android test project项目,名称Test;




2)生成资源文件,使用aapt生成R.java类文件,aapt所在路径android-sdk-windows\platform-tools\aapt.exe:
E:\Users\Administrator\workspace\Test>aapt package -f -m -J gen -S res -M AndroidManifest.xml -I E:\android-sdk_r23.0.2-windows\android-sdk-windows\platforms\android-18\android.jar
说明:
-f -m -J gen 代表按覆盖的形式在gen目录下生成带包路径的R.java;
-f force overwrite of existing files;
-m make package directories under location specified by -J
-J specify where to output R.java resource constant definitions
-J后面跟的是生成目录;-S后面跟的是资源目录;-M后面跟的是AndroidManifest.xml;-I后面跟的是使用的AndroidAPI的jar;


 
3)javac.exe编译.java类文件生成class文件,javac所在路径C:\Program Files\Java\jdk1.6.0_43\bin\javac.exe
E:\Users\Administrator\workspace\Test>javac -encoding utf-8 -target 1.6 -d bin -bootclasspath E:\android-sdk_r23.0.2-windows\android-sdk-windows\platforms\android-18\android.jar gen\android\support\v7\appcompat\test\*.java src\android\support\v7\appcompat\test\*.java
说明:-target:jdk版本;-d:指定生成的class类文件存放的位置;-bootclasspath:覆盖引导类文件的位置;-encoding:后面跟字符编码,避免出现乱码;




4)使用dx.bat命令行脚本生成classes.dex文件,dx.bat所在路径android-sdk-windows\tools\dx.bat
E:\Users\Administrator\workspace\Test>dx.bat --dex --output=E:\Users\Administrator\workspace\Test\bin\classes.dex E:\Users\Administrator\workspace\Test\bin\classes
说明:--output:生成的dex文件存放路径;最后带上class文件所在目录,不需要加包目录




5)使用aapt.exe生成资源包文件,aapt.exe所在路径android-sdk_r23.0.2-windows\android-sdk-windows\platform-tools\aapt.exe
E:\Users\Administrator\workspace\Test>aapt.exe package -f -M AndroidManifest.xml -S res -A assets -I E:\android-sdk_r23.0.2-windows\android-sdk-windows\platforms\android-18\android.jar -F bin\resourcesLater
说明:-S:资源目录;-M:AndroidManifest.xml文件;-I:导入用的jar文件;-F:后面跟生成的资源文件存放位置,生成的资源文件名是自己新建的




6)使用apkbuilder.bat生成未签名的apk安装文件,apkbuilder.bat所在路径android-sdk_r23.0.2-windows\android-sdk-windows\tools\apkbuilder.bat。
(使用该命令时:会提示该工具已过时,Google不推荐使用。而推荐使用的是:com.android.ant.ApkBuilderTask,但apk仍能成功生成)
E:\Users\Administrator\workspace\Test>apkbuilder E:\Users\Administrator\workspace\Test\bin\HelloWorld.apk -u -z E:\Users\Administrator\workspace\Test\bin\resourcesLater -f E:\Users\Administrator\workspace\Test\bin\classes.dex -rf E:\Users\Administrator\workspace\Test\src


THIS TOOL IS DEPRECATED. See --help for more information.
说明:-z:资源打包文件;-f:类打包文件;-rf:源代码目录;






(备注:此步骤没有成功给apk签名)
7)使用jarsigner.exe对未签名的包进行apk签名,jarsigner.exe所在路径C:\Program Files\Java\jdk1.6.0_43\bin\jarsigner.exe
E:\Users\Administrator\workspace\Test>jarsigner -verbose -keystore E:\Users\zhengshu_apk -signedjar E:\Users\Administrator\workspace\Test\bin\HelloWorld.apk E:\Users\Administrator\workspace\Test\bin\HelloWorld.apk.mydeystore
说明:-keystore:keystore文件;-signedjar:签名后的文件;后面还有未签名文件和key的alias




用法:jarsigner [选项] jar 文件别名
       jarsigner -verify [选项] jar 文件


[-keystore <url>]           密钥库位置


[-storepass <口令>]         用于密钥库完整性的口令


[-storetype <类型>]         密钥库类型


[-keypass <口令>]           专用密钥的口令(如果不同)


[-sigfile <文件>]           .SF/.DSA 文件的名称


[-signedjar <文件>]         已签名的 JAR 文件的名称


[-digestalg <算法>]    摘要算法的名称


[-sigalg <算法>]       签名算法的名称


[-verify]                   验证已签名的 JAR 文件


[-verbose]                  签名/验证时输出详细信息


[-certs]                    输出详细信息和验证时显示证书


[-tsa <url>]                时间戳机构的位置


[-tsacert <别名>]           时间戳机构的公共密钥证书


[-altsigner <类>]           替代的签名机制的类名


[-altsignerpath <路径列表>] 替代的签名机制的位置


[-internalsf]               在签名块内包含 .SF 文件


[-sectionsonly]             不计算整个清单的散列


[-protected]                密钥库已保护验证路径


[-providerName <名称>]      提供者名称


[-providerClass <类>        加密服务提供者的名称
  [-providerArg <参数>]] ... 主类文件和构造函数参数


E:\Users\Administrator\workspace\Test


生成和运行apk文件相关的组件:

 

apk文件的编译流程图如下:

下面逐一说明:

项目的源文件结构如下:

[html] view plaincopy
  1. E:\Example\  
  2. │  AndroidManifest.xml  
  3. │    
  4. ├─assets  
  5. ├─res  
  6. │  ├─drawable-hdpi  
  7. │  │      icon.png  
  8. │  │        
  9. │  ├─drawable-ldpi  
  10. │  │      icon.png  
  11. │  │        
  12. │  ├─drawable-mdpi  
  13. │  │      icon.png  
  14. │  │        
  15. │  ├─layout  
  16. │  │      main.xml  
  17. │  │        
  18. │  └─values  
  19. │          strings.xml  
  20. │            
  21. └─src  
  22.     └─net  
  23.         └─claudxiao  
  24.             └─example  
  25.                     Example.java  


1、从res生成R.java

mkdir gen

aapt package -f -m -J gen -S res -I “E:\Program Files\Android\android-sdk-windows\platforms\android-7\android.jar” -M AndroidManifest.xml

其中,-f将覆盖已有结果,-m -J gen指定输出路径,-S指定资源文件目录,-I指定要包含的包,-M指定AndroidMenifest.xml文件。

2、将.java编译为.class

mkdir bin

javac -encoding GB18030 -target 1.6 -bootclasspath “E:\Program Files\Android\android-sdk-windows\platforms\android-7\android.jar” -d bin src\net\claudxiao\example\Example.java gen\net\claudxiao\Example\R.java

其中,-target指定类文件的虚拟机版本,-bootclasspath覆盖引导类文件的位置,-d指定输出路径。

3、将.class编译为classes.dex

dx.bat –dex –output=E:\Example\bin\classes.dex E:\Example\bin

注意这里必须用绝对路径。

4、将资源文件打包

aapt package -f -M AndroidManifest.xml -S res -A assets -I “E:\Program Files\Android\android-sdk-windows\platforms\android-7\android.jar” -F bin\resources.ap_

-F指定输出的apk文件。

5、打包成未签名apk文件

apkbuilder.bat E:\Example\bin\Example_unsigned.apk -u -z E:\Example\bin\resources.ap_ -f E:\Example\bin\classes.dex -rf E:\Example\src

这个命令的常用格式为:

apkbuilder ${output.apk.file} -u -z ${packagedresource.file} -f ${dex.file} -rf ${source.dir} -rj ${libraries.dir}

参数必须使用绝对路径。

此外,运行后提示这一工具即将被废弃,但我没有找到新的替代工具是什么。

6、生成一个签名

keytool -genkey -alias android.keystore -keyalg RSA -validity 20000 -keystore android.keystore

当前目录下生成了一个android.keystore文件

7、对apk文件签名

jarsigner -keystore E:\Example\android.keystore -storepass claudxiao -keypass claudxiao -signedjar E:\Example\bin\Example.apk E:\Example\bin\Example_unsigned.apk android.keystore

这个命令的常用格式为:

jarsigner -keystore ${keystore} -storepass ${keystore.password} -keypass ${keypass} -signedjar ${signed.apkfile} ${unsigned.apkfile} ${keyalias}

至此,bin\Example.apk就是一个可以安装的apk文件了。作为对比,现在的目录结构如下:

[html] view plaincopy
  1. E:\Example\  
  2. │  android.keystore  
  3. │  AndroidManifest.xml  
  4. │    
  5. ├─assets  
  6. ├─bin  
  7. │  │  classes.dex  
  8. │  │  Example.apk  
  9. │  │  Example_unsigned.apk  
  10. │  │  resources.ap_  
  11. │  │    
  12. │  └─net  
  13. │      └─claudxiao  
  14. │          └─example  
  15. │                  Example.class  
  16. │                  R$attr.class  
  17. │                  R$drawable.class  
  18. │                  R$layout.class  
  19. │                  R$string.class  
  20. │                  R.class  
  21. │                    
  22. ├─gen  
  23. │  └─net  
  24. │      └─claudxiao  
  25. │          └─example  
  26. │                  R.java  
  27. │                    
  28. ├─res  
  29. │  ├─drawable-hdpi  
  30. │  │      icon.png  
  31. │  │        
  32. │  ├─drawable-ldpi  
  33. │  │      icon.png  
  34. │  │        
  35. │  ├─drawable-mdpi  
  36. │  │      icon.png  
  37. │  │        
  38. │  ├─layout  
  39. │  │      main.xml  
  40. │  │        
  41. │  └─values  
  42. │          strings.xml  
  43. │            
  44. └─src  
  45.     └─net  
  46.         └─claudxiao  
  47.             └─example  
  48.                     Example.java  

8. 对齐

     如果apk是Release模式,则必须使用zipalign工具进行对齐,对齐可减少内存使用。


0 0