8. Android加载流程(打包与启动)

移动安全的学习离不开对Android加载流程的分析,包括Android虚拟机,Android打包,启动流程等...

这篇文章  就对Android的一些基本加载进行学习。

Android虚拟机

Android开发中接触的是与Java虚拟机类似的的Dalvik虚拟机和ART虚拟机

Dalvik虚拟机

什么是Dalvik虚拟机

Dalvik虚拟机简称Dalvik VM或者DVM,是Google专门为Android平台开发的虚拟机,它运行在Android运行库中,需要注意的是DVM并不是一个Java虚拟机(Jvm虚拟机)

DVM与JVM虚拟机的区别

1.基于的架构不同

Jvm基于栈,需要去栈中读写数据,所需要的指令会更多,这样会导致速度慢,对于性能有限的移动设备,显然不是很适合。

DVM基于寄存器,它没有基于栈的虚拟机在拷贝数据而使用的大量的出入栈指令,同时指令更紧凑更简洁。但是由于显示指定了操作数,所以基于寄存器的指令会比基于栈的指令要大,但是由于指令数量的减少,总的代码数不会增加多少。

2.执行的字节码不同

JVM虚拟机中Java代码从编写到执行的过程:

1) 编写Java代码

2) 所有的Java代码通过Java编译器(javac)编译成java字节码,即.class文件

3) Java字节码在Java虚拟机上被解释成机器语言后,程序执行

DVM虚拟机Java代码从编写到执行的过程:

1) 编写Java代码

2) 所有的Java代码通过Java编译器(javac)编译成java字节码,即.class文件

3) Java字节码通过Android的dx工具转换成Dalvik字节码,即.dex文件

4) Dalvik字节码在Dalvik虚拟机上运行

文件结构对比图

ART虚拟机

ART虚拟机是Android4.4发布的,用来替换Dalvik虚拟机,Android 4.4默认采用的还是DVM,不过系统会提供一个选项来开启ART。在Android 5.0时,默认采用ART。

ART与DVM虚拟机的区别

1.DVM虚拟机中应用每次运行时,字节码都需要通过即时编译器转换成机器码,这会使应用的运行效率降低,而在ART中,系统在安装应用时会进行一次预编译,将字节码预先编译成机器码并存储在本地,这样应用每次运行时就不需要执行编译,提升了运行效率。

2.ART由于将字节码预先编译成机器码存储在本地,所以ART虚拟机占用空间比Dalvik大。

Apk打包流程

Android构建系统编译的应用资源和源代码,然后将它们打包成可测试、部署、签署和分发的 APK。

一般使用 Android Studio开发的时候使用Gradle构建工具包来自动执行和管理构建流程,同时也可以灵活地自定义构建配置。

在了解Android打包流程之前,先查看一个apk包内容,可以知道它里面都有哪些文件组成:

文件或目录 说明
assets文件夹 存放需要打包到APK中的静态文件
lib文件夹 存放应用程序依赖的native库文件
META-INF文件夹

1.该目录下存放的是签名信息,用来保证apk包的完整性和系统的安全性

2.CERT.RSA   这个文件保存了签名和公钥证书

3.CERT.SF  这个是对每个文件的头3行进行SHA1 hash

4.MANIFEST.MF  版本号以及每一个文件的哈希值(BASE64),包括资源文件。这个是对每个文件的整体进行SHA1(hash)。

res文件夹 存放资源文件的目录(图片,文本,xml布局)
AndroidManifest.xml 一个清单文件,它描述了应用的名字、版本、权限、注册的服务等信息。
classes.dex java源码编译经过编译后生成的dalvik字节码文件,主要在Dalvik虚拟机上运行的主要代码部分
resources.arsc 用来记录资源文件和资源ID之间的映射关系,用来根据资源ID寻找资源

知道了apk包的内容,会更好的理解Android打包流程:

先了解一下各个步骤使用的工具(绿色框):

名称 功能介绍 在操作系统中的路径
aapt Android资源打包工具,并生成R.java和resources.arsc文件 ${ANDROID_SDK_HOME}/platform-tools/appt
aidl Android接口描述语言.aidl文件转化为.java文件的工具 ${ANDROID_SDK_HOME}/platform-tools/aidl
javac

Java Compiler(编译器)将R.java、AIDL接口生成的java文件、应用代码java文件编译成.class文件。

${JDK_HOME}/javac或/usr/bin/javac

dex 转化.class文件为Davik VM能识别的.dex文件 ${ANDROID_SDK_HOME}/platform-tools/dx
apkbuilder

将资源文件和.dex文件生成未签名的.apk文件

${ANDROID_SDK_HOME}/tools/opkbuilder
jarsigner .jar文件的签名工具 ${JDK_HOME}/jarsigner或/usr/bin/jarsigner
zipalign

字节码对齐工具

${ANDROID_SDK_HOME}/tools/zipalign

整个apk打包流程为:

  1. 通过aapt工具进行资源文件(包括AndroidManifest.xml、布局文件、各种xml资源等)的打包,生成R.java文件。
  2. 通过aidl工具处理AIDL文件,生成相应的Java文件。
  3. 通过Javac工具编译项目源码,生成Class文件。
  4. 通过dx工具将所有的Class文件转换成DEX文件,该过程主要完成Java字节码转换成Dalvik字节码,压缩常量池以及清除冗余信息等工作。
  5. 通过apkbuilder具将资源文件、DEX文件打包生成APK文件。
  6. 利用jarsigner对生成的APK文件进行签名。
  7. 如果是正式版的APK,还会利用ZipAlign工具进行对齐处理,对齐的过程就是将APK文件中所有的资源文件举例文件的起始距离都偏移4字节的整数倍,这样通过内存映射访问APK文件的速度会更快。

-------------------------------------------------------------------

具体每一步打包流程为: 

1. aapt阶段:

使用aapt来打包res资源文件,生成R.java、resources.arsc和res文件(二进制 & 非二进制如res/raw和pic保持原样)

  • res目录,有9种子目录
  • R.java文件。里面拥有很多个静态内部类,比如layout,string等。每当有这种资源添加时,就在R.java文件中添加一条静态内部类里的静态常量类成员,且所有成员都是int类型。
  • resources.arsc文件。这个文件记录了所有的应用程序资源目录的信息,包括每一个资源名称、类型、值、ID以及所配置的维度信息。我们可以将这个文件想象成是一个资源索引表,这个资源索引表在给定资源ID和设备配置信息的情况下,能够在应用程序的资源目录中快速地找到最匹配的资源。

2. aidl阶段:

AIDL,Android接口定义语言,Android提供的IPC的一种独特实现。这个阶段处理.aidl文件,生成对应的Java接口文件。

3. Java Compiler阶段:

通过Java Compiler编译R.java、Java接口文件、Java源文件,生成.class文件。

4. dex阶段:

通过dex命令,将.class文件和第三方库中的.class文件处理生成classes.dex。

5. apkbuilder阶段:

将 classes.dex,resources.arsc,res文件夹(res/raw资源被原装不动地打包进APK之外,其它的资源都会被编译或者处理)、Other Resources(assets文件夹),AndroidManifest.xml打包成apk文件。

6. Jarsigner阶段

对apk进行签名,可以进行Debug和Release 签名。

7. 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 目录下

Android启动流程

这里不再多说,推一下大佬博客:

https://www.jianshu.com/p/9f978d57c683

讲的很详细

猜你喜欢

转载自www.cnblogs.com/bmjoker/p/11825679.html