Apk构建总结之一打包流程及安装流程

一. 分析已经打好的apk

要了解APK的打包流程,我们首先来了解下打包完成以后APK包里面包含哪些东西。.apk文件其实就是一个压缩文件,把文件的后缀改成.zip就可以用解压软件解压了:

1. 将apk后缀改成rar包

apk文件

rar文件

2. 解压rar包

目录

apk是一个压缩包,里面有lib,META-INF,classes.dex,res,resources.arsc文件夹和文件。下面看看它们各自的作用。

  • assets资源。
  • lib不是每个apk都有的,主要看项目,文件夹里面存放的是so动态链接库,so动态链接库不需要做处理。
  • META-INF是签名文件夹,里面有三个文件。
  • res:除图片和 res/raw 文件夹下的文件外,其余的 xml 文件都被 aapt 编译成二进制的 xml 文件,里面还会分animator,anim,color,drawable,layout,menu和raw这几个文件夹。
  • AndroidManifest.xml:经过 aapt 编译后的二进制的 xml 文件,它位于整个项目的根目录,描述了package中暴露的组件(activities, services, 等等),他们各自的实现类,各种能被处理的数据和启动位置。 除了能声明程序中的Activities, ContentProviders, Services, 和Intent Receivers,还能指定permissions和instrumentation(安全控制和测试)。这个文件是很重要的,里面有我们的Android四大组件和申请的权限。
  • classes.dex是.dex文件,就是我们写的java代码经过处理得到的。如果做了拆包那么会有classes1.dex,classes2.dex ...多个classes.dex文件。
  • resources.arsc记录了所有的应用程序资源目录的信息,包括每一个资源名称、类型、值、ID以及所配置的维度信息。我们可以将这个resources.arsc文件想象成是一个资源索引表,这个资源索引表在给定资源ID和设备配置信息的情况下,能够在应用程序的资源目录中快速地找到最匹配的资源。

我们发现xml文件都不能直接被识别了这是因为:xml文件都被aapt编译成二进制的xml文件,将文本格式的xml转为二进制格式的xml原因有以下两点:二进制格式的XML文件占用空间更小;二进制格式的XML文件解析速度更快。

二. 打包的详细流程

1.编译打包流程图

Android Studio默认采用gradle组织完成打包过程,对开发者来说简单的执行相关的task即可,这种透明的打包过程也让我们忽略了很多细节。


image.png

打包工具详解.

工具名称 功能介绍 路径
aapt Android资源打包工具 打包res资源文件,生成R.java、resources.arsc和res文件(二进制 & 非二进制如res/raw和pic保持原样) {SDK_PATH}/platform-tools/{tools_version}/appt.exe
aidl Android接口描述语言转化为.java文件的工具 {SDK_PATH}/platform-tools/{tools_version}/aidl.exe
javac Java Compiler java代码转class文件 {JDK_HOME}/javac
dex 转化.class文件为Davik VM能识别的.dex文件 {JDK_HOME}/platform-tools/{tools_version}/dx.bat
apkbuilder 所有没有编译的资源,如images、assets目录下资源,编译过的资源和.dex文件都会被apkbuilder工具打包到最终的.apk文件中 {JDK_HOME}/tools/opkbuilder
jarsigner .jar文件的签名工具,一旦APK文件生成,它必须被签名才能被安装在设备上。一种是用于调试的debug.keystore 一种就是用于发布正式版本的release.keystore {JDK_HOME}/jarsigner
zipalign 字节码对齐工具,对齐的主要过程是将APK包中所有的资源文件距离文件起始偏移为4字节整数倍,这样通过内存映射访问apk文件时的速度会更快。对齐的作用就是减少运行时内存的使用。 {JDK_HOME}/tools/zipalign

2.编译打包步骤

(1.) 打包资源文件,生成R.java文件

打包资源文件的工具是aapt(The Android Asset Packaing Tool),目录 sdk\build-tools\25.0.0\aapt。
在这个过程中,项目中的AndroidManifest.xml文件和布局文件XML都会编译,然后生成相应的R.java,另外AndroidManifest.xml会被aapt编译成二进制。
存放在APP的res目录下的资源,该类资源在APP打包前大多会被编译,变成二进制文件,并会为每个该类文件赋予一个resource id。对于该类资源的访问,应用层代码则是通过resource id进行访问的。
Android应用在编译过程中aapt工具会对资源文件进行编译,并生成一个resource.arsc文件,resource.arsc文件相当于一个文件索引表,记录了很多跟资源相关的信息。

(2.) 处理aidl文件,生成相应的Java文件

处理aidl文件的工具是aidl(Android Interface Definition Language),即Android接口描述语言,目录 sdk\build-tools\25.0.0\aidl。
aidl工具解析接口定义文件然后生成相应的Java代码接口供程序调用。如果在项目没有使用到aidl文件,则可以跳过这一步。

(3.) 编译项目源代码,生成class文件

编译源代码使用工具是 Java编译器(javac)
项目中所有的Java代码,包括R.java和.aidl文件,都会变Java编译器(javac)编译成.class文件,生成的class文件位于工程中的bin/classes目录下。

(4.) 转换所有的class文件,生成classes.dex文件

这过程使用工具 dx(dex)生成可供Android系统Dalvik虚拟机执行的classes.dex文件,工具目录(sdk\build-tools\25.0.0\dx)。
任何第三方的libraries和.class文件都会被转换成.dex文件。dx工具的主要工作是将Java字节码转成 Dalvik字节码、压缩常量池、消除冗余信息等。

(5.) 打包生成APK文件

打包的工具apkbuilder,目录 android-sdk/tools,apkbuilder为一个脚本文件,实际调用的是(sdk\tools\lib)文件中的com.android.sdklib.build.ApkbuilderMain类。
所有没有编译的资源,如images、assets目录下资源(该类文件是一些原始文件,APP打包时并不会对其进行编译,而是直接打包到APP中,对于这一类资源文件的访问,应用层代码需要通过文件名对其进行访问);
编译过的资源和.dex文件都会被apkbuilder工具打包到最终的.apk文件中。

(6.) 对APK文件进行签名

一旦APK文件生成,它必须被签名才能被安装在设备上。
在开发过程中,主要用到的就是两种签名的keystore。一种是用于调试的debug.keystore,它主要用于调试,在Eclipse或者Android Studio中直接run以后跑在手机上的就是使用的debug.keystore;
另一种就是用于发布正式版本的relese.keystore,需要开发者自己配置。

(7.) 对签名后的APK文件进行对齐处理

如果你发布的apk是正式版的话,就必须对APK进行对齐处理,用到的工具是zipalign,目录 sdk\build-tools\25.0.0\zipalign。
对齐的主要过程是将APK包中所有的资源文件距离文件起始偏移为4字节整数倍,这样通过内存映射访问apk文件时的速度会更快。对齐的作用就是减少运行时内存的使用。

综上所述, Android SDK中build-tools目录提供了各种程序, 都是独立可运行的,可以认为Android Studio编译打包过程是对这些工具的封装。

三.Android SDK 目录结构

通过上文可以了解到APK打包的脚本都是在SDK文件夹下面的:


SDK目录结构
1.build-tools目录
build-tools

编译工具目录,包含了转化为davlik虚拟机的编译工具,比如adb、和aapt、aidl、dx等文件。

2.emulator目录

Android模拟器模拟器目录。

3.extras目录

该文件下存放了Google提供的USB驱动,Intel提供的硬件加速附件工具包。

4.platforms目录
image.png

是每个平台SDK真正的文件,存放不同版本的Android系统。对应android studio build.gradle中的compileSdkVersion

5.platform-tools目录
platform-tools

各个版本的通用工具。比如 adb、sqlite3、fastboot等.

6.sources目录
sources

包含了各个版本的SDK源码。

7.system-images
system-images

存放的是创建Android虚拟机时的镜像文件(已经编译好的镜像文件,模拟器可以直接加载)。

8.tools

tools:这个文件夹下存放了大量Android开发、调试的工具。包括测试、调试、第三方工具。模拟器、数据管理工具等。

四. Android Studio工程结构。

项目主结构

1.gradle目录。

gradle

gradle 运行时自动生成的目录(自动编译工具产生的文件),版本由wrapper指定。一般情况不做修改,不需要纳入项目源代码管理中。

2..idea目录。

idea

Intellij IDEA 运行时候生成的文件目录,一般情况不做修改,不需要纳入项目源代码管理中。

3.app(module)目录。

image.png
  • app/build:app模块编译输出的文件
  • app/libs: 放置引用的类库文件
  • app/src: 放置应用的主要文件目录
  • app/src/androidTest:单元测试目录
  • app/src/main:主要的项目目录和代码
  • app/src/main/assets:放置原生文件,里面的文件会保留原有格式,文件的读取需要通过流
  • app/src/main/java:项目的源代码
  • app/src/main/res:项目的资源
  • app/src/main/res/anim:存放动画的XML文件
  • app/src/main/res/drawable:存放各种位图文件(.png,.jpg,.9png,.gif等)和drawable类型的XML文件
  • app/src/main/res/drawable-v24:存放自定义Drawables类(Android API 24开始,可在XML中使用)
  • app/src/main/res/layout:存放布局文件
  • app/src/main/res/menu:存放菜单文件
  • app/src/main/res/mipmap-hdpi:存放高分辨率图片资源
  • app/src/main/res/mipmap-mdpi:存放中等分辨率图片资源
  • app/src/main/res/mipmap-xdpi:存放超高分辨率图片资源
  • app/src/main/res/mipmap-xxdpi:存放超超分辨率图片资源
  • app/src/main/res/mipmap-xxxdpi:存放超超超高分辨率图片资源
  • app/src/main/res/raw:存放各种原生资源(音频,视频,一些XML文件等)
  • app/src/main/res/values: 存放各种配置资源(颜色,尺寸,样式,字符串等)
  • app/src/main/res/values/attrs.xml:自定义控件时用的较多,自定义控件的属性
  • app/src/main/res/values/arrays.xml:定义数组资源
  • app/src/main/res/values/colors.xml:定义颜色资源
  • app/src/main/res/values/dimens.xml:定义尺寸资源
  • app/src/main/res/values/string.xml:定义字符串资源
  • app/src/main/res/values/styles.xml:定义样式资源
  • app/src/main/res/values-v11:在API 11+的设备上调用
  • app/src/main/res/values-v14:在API 14+的设备上调用
  • app/src/main/res/values-v21:在API 21+的设备上调用
  • app/src/main/res/AndroidManifest.xml:项目的清单文件(名称、版本、SDK、权限等配置信息)
  • app/src/.gitignore:忽略的文件或者目录
  • app/app.iml:app模块的配置文件
  • app/build.gradle:app模块的gradle编译文件
  • app/proguard-rules.pro:app模块的代码混淆配置文件

4.gradle目录及配置项.

image.png
  • gradle/wrapper/gradle-wrapper.jar
  • gradle/wrapper/gradle-wrapper.properties 主要指定了该项目需要什么版本的Gradle,从哪里下载该版本的Gradle,下载下来放到哪里
  • .gitignore: 忽略的文件或者目录
  • build.gradle:项目的gradle编译文件
  • gradle.properties: gradle相关的全局属性设置
  • gradlew: 编译脚本,可以在命令行执行打包
  • gradlew.bat:windows下的gradle wrapper可执行文件
  • local.properties:配置SDK/NDK所在的路径
  • MyApplication.iml:保存该模块的相关信息
  • settings.gradle:设置相关的gradle脚本

五. APk安装流程

1. 概述

众所周知,Android应用最终是打包成.apk格式(其实就是一个压缩包),然后安装至手机并运行的。APK即Android Package的缩写。
应用程序管理服务PackageManagerService安装应用程序的过程,其实就是解析析应用程序配置文件AndroidManifest.xml的过程,并从里面得到得到应用程序的相关信息,
例如得到应用程序的组件Activity、Service、Broadcast Receiver和Content Provider等信息,有了这些信息后,通过ActivityManagerService这个服务,我们就可以在系统中正常地使用这些应用程序了。

2. Android应用APK的四种安装方式

  • 系统应用安装:开机时加载系统的APK和应用,没有安装界面;
  • 网络下载应用安装:通过各种market应用完成,没有安装界面;
  • ADB工具安装:即通过Android的SDK开发tools里面的adb.exe程序安装,没有安装界面;
  • 第三方应用安装:通过SD卡里的APK文件安装(比如双击APK文件触发),有安装界面,系统默认已经安装了一个安装卸载应用的程序,即由packageinstaller.apk应用处理安装及卸载过程的界面。

3. 应用安装涉及到的目录

  • /system/app :系统自带的应用程序,获得adb root权限才能删除
  • /data/app :用户程序安装的目录。安装时把apk文件复制到此目录
  • /data/data :存放应用程序的数据
  • /data/dalvik-cache:将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,当然,ART–Android Runtime的可执行文件格式为oat,启用ART时,系统会执行dex文件转换至oat文件)
  • /data/system :该目录下的packages.xml文件,类似于Windows的注册表,这个文件是在解析apk时由writeLP()创建的,里面记录了系统的permissions,以及每个apk的name,codePath,flags,ts,version,uesrid等信息,这些信息主要通apk的AndroidManifest.xml解析获取,解析完apk后将更新信息写入这个文件并保存到flash,下次开机直接从里面读取相关信息添加到内存相关列表中。当有apk升级,安装或删除时会更新这个文件。
  • /data/system/packages.xml中内容详解(这里列举的标签内容不一定完整,只是列举核心内容,packages.xml的完整定义详见官方文档):

4.安装流程

拷贝apk文件到指定目录

在Android系统中,apk安装文件是会被保存起来的,默认情况下,用户安装的apk首先会被拷贝到 /data/app 目录下。
/data/app目录是用户有权限访问的目录,在安装apk的时候会自动选择该目录存放用户安装的文件,而系统出厂的apk文件则被放到了 /system 分区下,包括 /system/app,/system/vendor/app,以及 /system/priv-app 等等,该分区只有Root权限的用户才能访问,这也就是为什么在没有Root手机之前,我们无法删除系统出厂的app的原因了。

解压apk,拷贝文件,创建应用的数据目录

为了加快app的启动速度,apk在安装的时候,会首先将app的可执行文件(dex)拷贝到 /data/dalvik-cache 目录,缓存起来。
然后,在/data/data/目录下创建应用程序的数据目录(以应用的包名命名),存放应用的相关数据,如数据库、xml文件、cache、二进制的so动态库等等。

解析apk的AndroidManifinest.xml文件

Android系统中,也有一个类似注册表的东西,用来记录当前所有安装的应用的基本信息,每次系统安装或者卸载了任何apk文件,都会更新这个文件。这个文件位于如下目录:
/data/system/packages.xml
系统在安装apk的过程中,会解析apk的AndroidManifinest.xml文件,提取出这个apk的重要信息写入到packages.xml文件中,这些信息包括:权限、应用包名、APK的安装位置、版本、userID等等。
由此,我们就知道了为啥一些应用市场和软件管理类的app能够很清楚地知道当前手机所安装的所有的app,以及这些app的详细信息了。
另外一件事就是Linux的用户Id和用户组Id,以便他可以获得合适的运行权限。
以上这些都是由PackageServiceManager完成的,下面我们会重点介绍PackageServiceManager。

显示快捷方式

这些应用程序只是相当于在PackageManagerService服务注册好了,如果我们想要在Android桌面上看到这些应用程序,还需要有一个Home应用程序,负责从PackageManagerService服务中把这些安装好的应用程序取出来,并以友好的方式在桌面上展现出来,例如以快捷图标的形式。在Android系统中,负责把系统中已经安装的应用程序在桌面中展现出来的Home应用程序就是Launcher了

保存安装信息

将app的包名、版本号、安装路径等保存在data/system/packages.xml文件中,以备下次安装时再次使用;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 说明 本文主要介绍和Gradle关系密切、相对不容易理解的配置,偏重概念介绍。部分内容是Android特有的(例如...
    jzj1993阅读 15,604评论 1 62
  • 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaoyanj...
    勤奋的pangdunhu阅读 2,022评论 0 1
  • Android Studio正式版早已经发布了,默认使用Gradle构建,GitHub上80%的Android项目...
    流哲羽阅读 2,863评论 1 13
  • 目的: jmeter 是一个开源性能测试工具,也是必须要掌握的,基础级别看网上的视频,高级的需要实践。 百科:Ap...
    飞翼_U阅读 1,145评论 0 3
  • 这几天简直就是增肥长肉大作战,一言不合就吃吃吃,大吃特吃,什么甜品烧烤周黑鸭奶茶香肠大鸡排,吃到上火拉肚子,嘴角都...
    山顶的黑狗兄阅读 202评论 0 0