我的世界皮肤做壁纸的网站,辽宁金帝建设集团网站,太原网站建设丿薇,网站制作多少钱资讯Markdown版本笔记我的GitHub首页我的博客我的微信我的邮箱MyAndroidBlogsbaiqiantaobaiqiantaobqt20094baiqiantaosina.comAndroid APK 打包流程 MD 目录 目录APK 的打包流程整体流程资源的编译和打包资源ID资源索引概况具体打包过程aapt阶段aidl阶段Java Compiler阶段dex阶段a…Markdown版本笔记我的GitHub首页我的博客我的微信我的邮箱MyAndroidBlogsbaiqiantaobaiqiantaobqt20094baiqiantaosina.com Android APK 打包流程 MD 目录 目录APK 的打包流程整体流程资源的编译和打包资源ID资源索引概况具体打包过程aapt阶段aidl阶段Java Compiler阶段dex阶段apkbuilder阶段Jarsigner阶段zipalign阶段 APK 的打包流程 参考 Android的包文件APK分为两个部分代码和资源所以打包方面也分为资源打包和代码打包两个方面这篇文章就来分析资源和代码的编译打包原理。 Android打包流程详图 整体流程 APK整体的的打包流程如下图所示 具体说来 通过AAPT工具进行资源文件包括AndroidManifest.xml、布局文件、各种xml资源等的打包生成R.java文件。通过AIDL工具处理AIDL文件生成相应的Java文件。通过Javac工具编译项目源码生成Class文件。通过DX工具将所有的Class文件转换成DEX文件该过程主要完成Java字节码转换成Dalvik字节码压缩常量池以及清除冗余信息等工作。通过ApkBuilder工具将资源文件、DEX文件打包生成APK文件。利用KeyStore对生成的APK文件进行签名。如果是正式版的APK还会利用ZipAlign工具进行对齐处理对齐的过程就是将APK文件中所有的资源文件举例文件的起始距离都偏移4字节的整数倍这样通过内存映射访问APK文件的速度会更快。上述流程都是Android Studio在编译时调用各种编译命令自动完成的具体说来如下所示 1、创建Android工程。 android create project \ -n packageTest2 \ -a MainActivity \ -k com.package.test2 \ -t android-23 \ -p ./PackageTest2 2、编译R文件 aapt package \ -f \ -J ./gen \ -M ./AndroidManifest.xml \ -S ./res/ \ -I /Users/RadAsm/Library/AndroidSDK/sdk/platforms/android-23/android.jar 3、编译源代码文件 javac -source 1.6 \ -target 1.6 \ -cp /Users/RadAsm/Library/AndroidSDK/sdk/platforms/android-23/android.jar \ ./src/com/packtest/test1/MainActivity.java ./src/com/packtest/test1/R.java \ -d ./gen/classes 4、编译DEX文件 dx --dex \ --verbose \ --output ./gen/dex/packtest1.dex ./gen/classes/ 5、生成APK文件 aapt package -f \ -J ./gen \ -M ./AndroidManifest.xml \ -S ./res/ \ -I /Users/RadAsm/Library/AndroidSDK/sdk/platforms/android-23/android.jar \ -F ./output/res.apk 6、APK文件对齐 zipalign -v -p 4 packagetest_unsigned.apk packagetest_aligned_unsigned.apk 7、APK签名 apksigner sign --ks my-release-key.jks my-app.apk 以上便是APK打包的整个流程我们再来总结一下 除了assets和res/raw资源被原装不动地打包进APK之外其它的资源都会被编译或者处理除了assets资源之外其它的资源都会被赋予一个资源ID打包工具负责编译和打包资源编译完成之后会生成一个resources.arsc文件和一个R.java前者保存的是一个资源索引表后者定义了各个资源ID常量。应用程序配置文件AndroidManifest.xml同样会被编译成二进制的XML文件然后再打包到APK里面去。应用程序在运行时通过AssetManager来访问资源或通过资源ID来访问或通过文件名来访问。理解了整体的流程我们再来看看具体的细节。 资源的编译和打包 在分析资源的编译和打包之前我们先来了解一下Android程序包里有哪些资源。 我们知道Android应用程序的设计也是代码与资源相分离的Android的资源文件可以分为两大类 assetsassets资源放在主工程assets目录下它里面保存一些原始的文件可以以任何方式来进行组织这些文件最终会原封不动的被打包进APK文件中。 获取asset资源也十分简单如下所示 InputStream is getAssets.open(fileName); resres资源放在主工程的res目录下这类资源一般都会在编译阶段生成一个资源ID供我们使用。 res资源包含了我们开发中使用的各种资源具体说来 animatoranimcolordrawablelayoutmenurawvaluesxml这些资源的含义大家应该都很熟悉这里就不再赘述。 上述9种类型的资源文件除了raw类型资源以及Bitmap文件的drawable类型资源之外其它的资源文件均为文本格式的XML文件它们在打包的过程中会被编译成二进制格式的XML文件。这些二进制格式的XML文件分别有一个字符串资源池用来保存文件中引用到的每一个字符串包括XML元素标签、属性名称、属性值以及其它的一切文本值所使用到的字符串。这样原来在文本格式的XML文件中的每一个放置字符串的地方在二进制格式的XML文件中都被替换成一个索引到字符串资源池的整数值这写整数值统一保存在 R.java类中R.java会和其他源文件一起编译到APK中去。 前面我们提到xml编写的Android资源文件都会编译成二进制格式的xml文件资源的打包都是由AAPT工具来完成的资源打包主要有以下流程 解析AndroidManifest.xml获得应用程序的包名称创建资源表。添加被引用资源包被添加的资源会以一种资源ID的方式定义在R.java中。资源打包工具创建一个AaptAssets对象收集当前需要编译的资源文件收集到的资源保存在AaptAssets对象对象中。将上一步AaptAssets对象保存的资源添加到资源表ResourceTable中去用于最终生成资源描述文件resources.arsc。编译values类资源这类资源包括数组、颜色、尺寸、字符串等值。给bag、style、array这类资源分配资源ID。编译xml资源文件编译的流程分为四步① 解析xml文件 ② 赋予属性名称资源ID ③ 解析属性值 ④ 将xml文件从文本格式转换为二进制格式。生成资源索引表resources.arsc。资源ID 每个Android项目里都有有一个R.java文件如下所示 public final class R {//...public static final class anim {public static final int abc_fade_in0x7f010000;}public static final class attr {public static final int actionBarDivider0x7f020000;}public static final class string {public static final int actionBarDivider0x7f020000;}//...
} 每个资源项后的整数就是资源ID资源ID是一个4字节的无符整数如下所示 最高字节是Package ID表示命名空间标明资源的来源Android系统自己定义了两个Package ID系统资源命名空间0x01 和 应用资源命名空间0x7f。次字节是Type ID表示资源的类型例如anim、color、string等。最低两个字节是Entry ID表示资源在其所属资源类型中所出现的次序。资源索引 上面提到最终生成的是资源索引表resources.arscAndroid正是利用这个索引表根据资源ID进行资源的查找为不同语言、不同地区、不同设备提供相对应的最佳资源。查找是通过Resources和AssetManger来完成的这个我们下面会讲。 resources.arsc 是一个编译后的二进制文件在Android Stduio里打开以后是这样的如下所示 可以看到resources.arsc里存放了各类资源的索引参数和配置信息。 resources.arsc的文件格式如下所示 注整个文件都是有一系列chuck块构成的chuck是整个文件的划分单位每个模块都是一个chuckchuck最前面是一个ResChunk_header的结构体用来描述整个chunk的信息更多关于索引表格式的细节可以查阅源码 ? ResourceTypes.h resources.arsc 索引表从上至下文件格式依次为 文件头数据结构用ResTable_header来描述用来描述整个文件的信息包括文件头大小文件大小资源包Package的数量等信息。全局字符串池存放所有的字符串所以资源复用这些字符串字符串里存放的是资源文件的路径名和资源值等信息。全局字符串池分为资源类型type字符串池和资源包会有多个例如系统资源包、应用资源包。资源包也被划分为以下几个部分 包头描述资源包相关信息。资源类型字符串池存放资源的类型。资源名称字符串池存放资源的名称。配置列表存放语音、位置等手机配置信息用来作为查找资源的标准。从这里可以看到resources.arsc索引表存在很多常量池常量池的使用目的也很明显就是提供资源的复用率减少resources.arsc索引表的体积提高索引效率。 概况 参考 Android APK是如何来的呢 怀着这个问题去查资料发现了下边这张图。 解压一个普通的apk文件后解压出来的文件包括 classes.dex.dex文件resources.arscresources resources文件AndroidManifest.xmlAndroidManifest.xml文件resuncompiled resourcesMETA-INF签名文件夹 MANIFEST.MF文件版本号以及每一个文件的哈希值(BASE64)包括资源文件。这个是对每个文件的整体进行SHA1(hash)。CERT.SF这个是对每个文件的头3行进行SHA1 hash。CERT.RSA这个文件保存了签名和公钥证书。具体打包过程 aapt阶段 使用aapt来打包res资源文件生成R.java、resources.arsc和res文件二进制 非二进制如res/raw和pic保持原样 res目录有9种子目录R.java文件。里面拥有很多个静态内部类比如layoutstring等。每当有这种资源添加时就在R.java文件中添加一条静态内部类里的静态常量类成员且所有成员都是int类型。resources.arsc文件。这个文件记录了所有的应用程序资源目录的信息包括每一个资源名称、类型、值、ID以及所配置的维度信息。我们可以将这个文件想象成是一个资源索引表这个资源索引表在给定资源ID和设备配置信息的情况下能够在应用程序的资源目录中快速地找到最匹配的资源。aidl阶段 AIDLAndroid接口定义语言Android提供的IPC的一种独特实现。 这个阶段处理.aidl文件生成对应的Java接口文件。 Java Compiler阶段 通过Java Compiler编译R.java、Java接口文件、Java源文件生成.class文件。 dex阶段 通过dex命令将.class文件和第三方库中的.class文件处理生成classes.dex。 apkbuilder阶段 将classes.dex、resources.arsc、res文件夹(res/raw资源被原装不动地打包进APK之外其它的资源都会被编译或者处理)、Other Resources(assets文件夹)、AndroidManifest.xml打包成apk文件。 Jarsigner阶段 对apk进行签名可以进行Debug和Release 签名。 zipalign阶段 release mode 下使用 aipalign 进行align即对签名后的apk进行对齐处理。 Zipalign是一个android平台上整理APK文件的工具它对apk中未压缩的数据进行4字节对齐对齐后就可以使用mmap函数读取文件可以像读取内存一样对普通文件进行操作。如果没有4字节对齐就必须显式的读取这样比较缓慢并且会耗费额外的内存。 在 Android SDK 中包含一个名为 zipalign 的工具它能够对打包后的 app 进行优化。 其位于 SDK 的 \build-tools\23.0.2\zipalign.exe 目录下 2019-2-18转载于:https://www.cnblogs.com/baiqiantao/p/10398653.html