创建build.xml local.properties project.properties --如果已经有这三个文件,请忽略此步骤
project.properties --这个文件通常是在创建android工程时已经创建好了!在工程主目录下可以找到。
build.xml--此文件需要创建,其具体创建过程如下:打开命令行,切换到工程目录下,执行命令 android update project -p . -t <target> -n <build name>
比如 d:/androidtest : android update project -p . -t 3 -n <buildTest>
具体参数解释如下:
-p 指项目所在目录,这里的.表示当前目录下;
-t 指工程对应的target,获取方式是:在cmd下输入命令android list targets,对应地返回数值(比如你项目选用的android平台是 4.2.2,那么对应的id是3,如下所示)
id: 3 or "android-17" Name: Android 4.2.2
-n 指的是build文件的name,可以自定义,也可以默认(默认取launcher对应的activity的名字);
完成后,工程目录如下:
-src
-res
-libs
-assets
-AndroidManifest.xml
-project.properties----------<android update project 生成>工程属性,指定target, proguard.config
-build.xml -------------------------<android update project 生成>ant工程文件
-local.properties ------------------ <android update project 生成>指定sdk.dir属性
-proguard-project.txt -------------<android update project 生成>个性化混淆配置文件
-ant.properties---------------------手动添加,可以放置自定义的ant属性
打包分以下两种方式:
1. 命令行:
cmd切换到项目目录下,执行命令 ant release(调用sdk/tool/ant目录下 build.xml打包) ,打包过程可看日志,打包成功后,自动将apk包 放到bin/目录下;
2. 用ant模式:
在eclipse模式下,点击项目下的build.xml文件(此build.xml里有如下代码:<import file="${sdk.dir}/tools/ant/build.xml" />,它实际上也是调用了sdk/tool/ant目录下 build.xml打包),右击,选择open with--Ant Editor ,在弹出来的outline视框中,找到 release,然后点击右键,选择Ant build,打包成功后,自动将apk包 放到bin/目录下;
打开build.xml文件,通常有 <property file="ant.properties" /> ,这个file文件里面记录的是 签名信息,通常包含四个参数:
key.store
key.alias
key.store.password
key.alias.password
此文件在调用build.xml运行打包命令时,会被调用,生成 签名的apk包;
如果用eclipse运行安装apk,不调用build.xml,不会生成签名的包;
经过签名的apk,解压出来,可以在META-INF下看到两个文件:CERT.RSA CERT.SF;
为了代码保密,增加反向工程的难度,在打包的时候需要对代码进行混淆,ADT支持混淆工具Proguard
参考 http://developer.android.com/intl/zh-CN/tools/help/proguard.html (英文权威版)。
设置 混淆 规则:
在项目录下,project.properties文件里,添加代码
proguard.config=proguard.cfg --.cfg文件需要自己添加混淆规则内容
或者使用注释里面的代码
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt --这是sdk自带的混淆规则文件
build.xml 运行打包过程中,会读取混淆规则文件,进行混淆处理,打包完成后,会在项目bin/ 目录 下生成proguard文件夹(如果用eclipse打包:点击项目名称,右键 android tools --Export Unsigned ....--生成apk,这种操作方式,产生的proguard文件夹直接在项目主目录下),包含以下内容:
dump.txt --文件中所有类文件间的内部结构
mapping.txt --列出了原始的类,方法和字段名与混淆后代码间的映射【重要!】
seeds.txt --列出了未被混淆的类和成员
usage.txt --列出了从.apk中删除的无用的代码,减小apk大小
build打包过程, 如果设置了混淆,它会调用此规则,生成 混淆后的APK;
因为android的app市场众多,聚划算android客户端分发的渠道达到60+,为统计或其他定制的需要,就产生了一个版本的app需要为各个market打包,每个market分配不同的channel id。channel id一般放置在asset文件,或者放在AndroidManifest的meta-data标签中,命名为 ttid.dat;<br>
ttid.dat --每个投放到市场的apk包,都包含此文件,它里面包含了此市场的渠道号,简称为ttid;市场上面下载的apk,它的所有request里面都会包含ttid这个参数,用来记录此渠道的应用的使用情况;<br>
如何打渠道包:<br>
执行build.xml中的ttid 对应的 target时,会去 读取ttid.txt文件(包含所有市场的渠道号),每行一个ttid,foreach任务循环打包,每次循环都会将ttid写入到asset/ttid.dat中,然后执行一次打包过程(具体循环过程可以参考 build.xml内代码);<br>
[编辑]build.xml
<property file="local.properties" /> <loadproperties srcFile="project.properties" /> --加载文件内容
<import file="${sdk.dir}/tools/ant/build.xml" /> --引用ant的打包文件,必须要有的
最重要的是 <target>标签,用来指定打包任务的类型,一般 需要 自定义,比如
<target name="test"> --任务名称
<xpath input="AndroidManifest.xml" expression="/manifest/@android:versionName" output="versionName" default="unknown" /> --查找versionName的值,并将它保存到变量versionName中
<echo message="name: ${versionName}"> --打印
</echo>
</target>
以上是一次 打包任务,在tasklist中,直接选择test,双击运行即可执行一遍此target;
查看每个项目的build,一般都包含多个build,在tasklist视图中可查看整个build的结构,并可以方便地选择执行哪个task;
[编辑]prguard.cfg
以下是 混淆用到的规则参数列表 ,供参考学习:
参数:
-include {filename} 从给定的文件中读取配置参数
-basedirectory {directoryname} 指定基础目录为以后相对的档案名称
-injars {class_path} 指定要处理的应用程序jar,war,ear和目录
-outjars {class_path} 指定处理完后要输出的jar,war,ear和目录的名称
-libraryjars {classpath} 指定要处理的应用程序jar,war,ear和目录所需要的程序库文件
-dontskipnonpubliclibraryclasses 指定不去忽略非公共的库类。
-dontskipnonpubliclibraryclassmembers 指定不去忽略包可见的库类的成员。
保留选项
-keep {Modifier} {class_specification} 保护指定的类文件和类的成员
-keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
-keepnames {class_specification} 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)
-keepclassmembernames {class_specification} 保护指定的类的成员的名称(如果他们不会压缩步骤中删除)
-keepclasseswithmembernames {class_specification} 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
-keepattributes {attribute_name,...} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, signature and InnerClasses.
-printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件
压缩
-dontshrink 不压缩输入的类文件
-printusage {filename}
-whyareyoukeeping {class_specification}
优化
-dontoptimize 不优化输入的类文件
-assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用
-allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员
混淆
-dontpreverify //不用预先检查
-verbose //输出详细的过程
-dontobfuscate 不混淆输入的类文件
-printmapping {filename} //指定混淆后,类或方法生成的map,后跟指定的路径及文件名 *.map
-applymapping {filename} 重用映射增加混淆
-obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively 混淆时应用侵入式重载
-useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames 混淆时不会产生形形×××的类名
-renamesourcefileattribute {string} 设置源文件中给定的字符串常量
一般来说,在混淆打包后的测试中,如果发现问题,就将有问题的类设置为keep(让它不参与混淆,以保证质量)
在网上找到一个客户端打包原理图解: