最近研究了一下Android打包apk的流程,简要描述一下。
我们可以跟随android的sdk目录下的tools/ant/build.xml文件的描述来一窥打包apk流程究竟。
首先这是用ant打包的过程,eclipse打包流程应该大抵一样。用ant打包前,如果project不是用ant创建的,先需要执行android update project -p /path/to/project。该命令会在project目录下生成相应的配置文件。如build.xml(与sdk下的那个不同),project.properties,local.properties等。生成的几个文件都是项目相关的配置参数等。ant打包需要build.xml配置文件,project下的配置文件包含sdk/tools/ant/build.xml文件。
project下的build.xml相对简单了,设定一些project属性,引用了project.properties,local.properties等文件。build.xml设定了ant的默认行为(target)是help。显示相应帮助。
sdk/tools/ant/build.xml相对复杂很多,一共有1300+行。乍看很多,粗粗分析开来,一块一块也相对较为明朗。即便我对ant配置一知半解,也看个大概明白。<property>就是设定一些key-value的属性,<target>就是ant对应的目标,类似于Makefile的那个目标。
这个build.xml相应地方做了良好的注释。这个文件内容分布大概如下:
1.定义一些覆盖默认设置的属性。还是有一些挺有意思的属性值得一看的,比如android.package.excludes,设定该属性可以排除编译一部分代码。再比如version.code,version.name可以替换AndroidManifest.xml中的相关版本内容。
2.自定义了一些任务。凭借我的揣测,这是ant提供的一些扩展,这些任务是通过${sdk.dir}/tools/lib/anttasks.jar这个jar包来导入定义的。定义了很多,列举一二,如com.android.ant.NewSetupTask,com.android.ant.AaptExecTask,com.android.ant.IfElseTask等等。
3.其它属性。主要是编译流程用到的一些变量属性,包含输入目录,输出目录,工具位置等。这里可以看见一些经常看到用到的目录和工具。比如src自不用多说,还有gen目录,libs目录等。此处加一段故事,很久之前,我是用Eclipse好的project在带我的bear那里用ant编译有问题,问题在于我将外部的jar包放在了lib目录下,ant编译的时候会找不到这个jar包了,但是放在libs里就可以了,到了这就可以解释了,因为build.xml暗暗的定义了这个默认的文件夹的名字。再插一句最新的adt也支持放在libs中而不需要做多余路径设定了。
4.宏定义。定义了一些多次用的流程为宏。比如do-only-if-not-library,如果不是android library project就怎样做。package-helper等等。
5.Build过程的一些Target。第一个是nodeps,很简单是设定了一个属性,来设定targets间是否存在依赖关系。然后有-per-clean,clean清空bin,gen目录做了这么些事。(前面加-的target,从某种程度来说是private的target,因为输入ant -xxx的时候,-xxx会当作ant的参数,而不是build的目标)
然后就涉及打包流程了。-setup,做一些初始化工作,创建bin目录等,设定一些属性等。-build-setup,也是做一些build的初始化工作。然后是-per-build这个是空的,这个是用来给用户做一些自定义设定或者实现预留的,后面类似这样预留的无内容的部分我就不讲了。然后是-code-gen,这个就有意思一些了,最为人熟知的android中的R文件就要生成了,生成R文件在这个过程做了定义,通过aapt程序(这个程序很有意思,这里略去不讲,没准下回会讲)生成R文件。-code-gen过程还有一些重量级的东西。比如生成用于进程通信的aidl文件相应类的生成,还有renderscript的生成。还有BuildConfig文件的生成。然后就是激动人心的compile编译过程了,就是javac做编译,生成class文件。这里有些令人激动的事情。就是Android为了代码复用,提出了library project的概念,某种程度上还不错,但是扩展能力有限,还是有些坑爹的,而且有一些限制。此处再插故事一则,我有3个project,分别标记为a,b,c,a,b分别是library project,然后依赖是c=>b=>a(c依赖于b,b依赖于a),我想对b做代码混淆,但是出现一些依赖问题。因为android的现在的这个build过程并不把在前面-code-gen生成的依赖的子library的R文件编译到这个library自己的这里,所以在混淆b的时候,会出现a中的R无法找到的问题,因为a中的R会被便已到c中,很混乱吧。事情是这样,但是错误在自己,因为对android的library和整个project的打包流程不清楚,所以造成了上面的窘境。其实根本不用混淆b工程,因为b工程的class会最终放到c中,最后在c中混淆就行了。晕了。。。
继续说打包流程,编译完了,然后就是-obfuscate混淆过程了,混淆默认只在release模式下才进行,内部有一些判断。关于混淆的一些介绍,可以参见我的上一篇博文《ProGuard总结和混淆Android代码中遇到的问题的解决方法以及寻找getSomething游戏》。然后是-dex,转.class到.dex过程。开发Android的都知道,Android没有用标准的jvm,而是自己专门为移动设备优化实现的dalvik vm。这个过程会把所有的.class文件打包到一个.dex文件中。
至此,代码build过程就结束了。全都结束了吗?还没有,Android还有编译资源,再说还没打成apk包呢。
跟资源处理有关的过程先是-crunch这个过程就是对png图片做一些压缩处理。具体怎么处理的咱就不细究了,想知道的话可以研究源代码去。然后又到了激动人心的资源打包过程-package-resources,这个过程就是用牛x的aapt,将所有res目录下的资源文件manifest等文件打包编译处理。这其中有一个对于.9.png的说明。我们知道.9.png的图片是带一圈透明画有黑点的图片。这个过程aapt会将.9.png处理,将透明带黑点写入二进制。和原来的图是不一样了的,逆向工程的时候对.9.png有很多限制。apktool的wiki上有相关说明。xda论坛上也有相关讨论。还有一点是将普通.png改为.9.png的后,ant全程打包是不会有问题的。但是aapt确实对这种情况做了抛出异常处理,所以我猜想是在crunch时做了什么处理,还未证实。
资源文件也build好了,然后对于debug或release。就是打包成apk。然后给apk签名,签名方式上两种模式有些不同处理。debug会进行debug签名,release需要你提供你的签名文件等。然后或进行zipalign操作,字节对齐。
至此,整个过程就结束了。
还有一些关于测试和安装卸载的target就不写了。
(重点过程,加粗标识了,看一遍加粗部分,基本就能知道个大概了)
分享到:
相关推荐
Gradle编译打包Android apk详细介绍 理解Gradle构建过程,解读Android Gradle插件的配置 阅读本文一定是要使用过Gradle生成apk,文中不会讲如何安装运行Gradle,如有需要可先看文末的参考文章。 APK包是一个ZIP...
unity3d配置Android环境,打包发布Apk流程详解-附件资源
unity配置Android打包发布Apk流程详解-附件资源
Android apk文件结构 打包编译的流程Android官网 配置构建 流程Configure your buildThe build processAPK文件结构assetsreslibMETA-INFAndroidManifest.xmlclasses.dexresources.arscAndroid完整打包流程详细介绍1....
android apk打包,用于上线。开发商可能通过使用相同的Package Name来混淆替换已经安装的程序,所以增加了签名。 后期再发布上线流程.
* [官方打包流程图](./apk/README.md#官方打包流程图) * [详细打包流程图](./apk/README.md#详细打包流程图) * [ant打包流程图](./apk/README.md#ant打包流程图) * [gradle打包简介](./apk/README.md#gradle打包...
unity3d发布apk在android虚拟机中运行的详细步骤(unity3d导出android apk),总的流程分为以下6个步骤: 1、安装java_jdk 2、配置java环境变量 3、更新android的sdk 4、从Unity3d中发布出apk文件 5、创建android虚拟机...
Android aapt自动打包工具 ...也可将资源文件编译成二进制文件,尽管你可能没有直接使用过aapt工具,但是build scripts和IDE插件会使用这个工具打包apk文件构成一个Android 应用程序。 aapt打包流程 aa
Github操作是测试或部署或构建APK的简便方法,无需使用travis ci或circel ci或jenkins。 它使我们可以直接从github构建,测试和部署代码。 您还可以按照操作所需的方式分配代码审阅,管理分支和分类问题。 无论您是...
主要介绍了Jenkins打包android应用时自动签名apk详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Android打包过程大致如图所示,整个流程就是将Java代码,资源文件以及第三方库整合成一个Apk文件,并对整合后的文件进行签名和优化对齐。整个过程可以简 单分为以下几个步骤: 资源预编译 为每一个非assert资源...
缘由:测试流程由 打包 找包准备上传 填写更新信息 然后上传 过于复杂 所以想要简化开发 阅读须知:需要读者了解如何在项目里面建立一个空的gradle plugin的过程,否则这篇文章不适合你 开始分析 我想要的效果是...
Android逆向基础思维导图,便捷整理思路,环境搭建、APK结构与反编译、APK打包流程、APK安装流程
流程图: 我们重点关心的是(1)这个过程的输入是什么?(2)这个过程的输出是什么?...Android资源打包工具 ${ANDROID_SDK_HOME}/platform-tools/appt aidl Android接口描述语言转化为.java文件的工具 ${
1.简介这是Unity Android APP il2cpp热更完美解决方案的Demo( )的说明。和现有的热更解决方案不同的是,他不会约会多余的语言(只是UnityyScript,c#...),对Unityy程序设计和编码没有任何限制。你可以在预先和...
Unity项目接入sdk的(android),包括接入流程,代码示例,jar导出,gradle打包问题解决方法
执行apktool b temp unsigned.apk 重新打包apk 执行 SignApk.jar 生成签名后的 apk 文件 执行 zipAlign 生成对齐优化后的 apk 文件 回到 3 替换新的渠道 完成打包 使用 JarSigner.jar 给 Apk 签名, SignApk....