纯ant命令行打包android apk之图文从原理角度完全详解android打包过程(打包系列教程之一)
打包系列教程目录:
纯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打包!打包系列教程概要如下:
今天就以mac系统为例,来分享一下通过ant命令行对android app进行打包,其他3篇将后续给出,这里并非使用android 官方提供的ant工具。本篇内容概要如下
一:搭建环境
1.先安装ant工具,可以到ant官网:http://ant.apache.org/ 下载即可
2.配置ant环境变量(mac平台)
打开命令行:输入 open .bash_profile 打开配置文件配置如下:
保存后,在命令行输入 source .bash_profile 刷新一下配置文件,然后在命令行输入 ant 回车 出现以下的结果则安装成功!
这里还需要用到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为案例:
(1). 生成用于应用的R.java;
这里要使用android官方提供的aapt工具,生成R.java文件,这个工具存于/SDK/build-tools下,因此需要
配置好环境变量(配置方法同上)。
先cd到该项目根目录下(别忘了哦),为了区分显示执行结果(因为eclipse工程存在gen和bin目录),我把存放R.java文件的目录放在桌面的ant文件夹下的gen,同时在同级目录创建bin目录,用于存放classes.dex文件(后面使用)
在我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文件:
(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
-bootclasspath <路径> 覆盖引导类文件的位置
-d <目录> 指定存放生成的类文件的位置
-sourcepath <路径> 指定查找输入源文件的位置(这里包含两个地方一个是src,一个是桌面gen生成的R.java)
回车运行,在桌面bin目录下生成如下文件:
(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文件的路径跟要处理文件是一样的。
回车运行,结果报错:
一开始咋一看是:
根据网上的资料显示这个是jar冲突造成的,但我没用jar包啊,就一个v4包,删了再运行还是报错;后来往下看才发现:
原来是这个错误:
这其实是jdk版本兼容性问题。我引入的jar包编译环境(比如是1.7)要高于android中默认的jdk编译版本(我用的是1.6)。要解决这个问题,
也很简单只要android项目的编译jdk版本要高于等于引入jar包的编译jdk版本,然后重新编译就好了。既然如此修改eclipse的jdk编译版本改为1.7即可:
重新执行第(2)步,再运行第(3)步,运行成功!生成classes.dex如下:
(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文件:
(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
(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
最后的“别名”一定要保证正确,不然会报如下错误:
参数含义:
-verbose 签名/验证时输出详细信息
-keystore 密钥库路径
-storepass 用于密钥库完整性的口令(密码)
-keypass 专用密钥的口令(密码)
-signedjar 已签名的 apk 文件的名称 (第一个apk是签名之后的文件, 第二个apk是需要签名的文件)
运行结果如下:
生成apk如下:
(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 existing.apk
-c 表示进行zipalign优化检测
-v 输出过程信息
现在我们就对刚才生成的apk包也就是signed_command4Ant.apk进行zipalign优化检测,我们在命令行输入如下信息:
zipalign -c -v 4 /Users/zejian/Desktop/ant/bin/signed_command4Ant.apk
4 这个数字表示检测4个字节对齐的意思。
从输出结果可以知道,未进行zipalign优化的apk,认证失败了!
那该怎么进行zipalign优化呢?可以使用如下语句
zipalign [-f] [-v] 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
输出结果如下:
好了,zipalign优化完成,在桌面ant文件的bin下生成了经过zipalign优化的zipalign_signed_command4Ant.apk包:
我们再次对已经进行过zipalign优化的apk进行检测,我们在命令行输入如下信息:
好了,整个android apk打包已经完成。其实这里有少处理了aidl文件,因为项目中没有,我也就没演示了。
有需要的话,大家可以看一下这篇文章 http://blog.csdn.net/sodino/article/details/6419498
最后附上整个流程图,供大家参考:
到此最简单的ant打包流程就梳理完了。
标签:
相关文章
-
无相关信息