不管是 Android 知识的学习 还是其他知识的学习 ,最好还是去 官网 学习。因为现在信息年代,很多博客只是复制粘贴,有可能有哪些地方是错误的,会对我们造成误导,当然并不是说我就不复制粘贴了。当然官网介绍的并不详细,我也参考其他博客,把我们需要知道的一些东西也都放到本博客中了。
关于apk签名,修改apk默认名称可以看我的另一篇博客,Android studio apk签名 必须明白的概念 流程 证书指纹获取 apk默认名称修改 详解,当然修改apk默认名称需要掌握一定的gradle 和 groovy语言的知识,也可以自己学习或可以参考我的相关博客,如下:
Groovy语言学习
Android Studio 中如何运行 groovy 程序
gradle学习参考博客
学习gradle的话,相关的东西还是挺多的,我暂时还没用写相关的博客,大家可以参考我gradle学习参考博客里面提供的地址进行学习,也可以自己找相关资源学习,当然最好还是去官网学习啊。
Gradle、Grovvy、Grovvy JDK文档
好了言归正传,下面 是 Google Android 开发者平台 配置构建 部分内容翻译而来,网上很多 “Android打包编译的流程 ” 相关博客 也复制了官网的内容。
The Android build system compiles app resources and source code, and
packages them into APKs that you can test, deploy, sign, and distribute.
Android Studio uses Gradle, an advanced build toolkit, to automate and
manage the build process, while allowing you to define flexible custom
build configurations. Each build configuration can define its own set of
code and resources, while reusing the parts common to all versions of
your app. The Android plugin for Gradle works with the build toolkit to
provide processes and configurable settings that are specific to
building and testing Android applications.
Android构建系统编译应用程序资源和源代码,并将它们打包成apk,您可以对其进行测试、部署、签名和分发。Android Studio使用高级构建工具包Gradle来自动化和管理构建过程,同时允许您定义灵活的自定义构建配置。每个构建配置都可以定义自己的代码和资源集,同时重用应用程序所有版本的通用部分。用于Gradle的Android插件与构建工具包一起工作,提供特定于构建和测试Android应用程序的流程和可配置设置。
Gradle and the Android plugin run independent of Android Studio. This
means that you can build your Android apps from within Android Studio,
the command line on your machine, or on machines where Android Studio is
not installed (such as continuous integration servers). If you are not
using Android Studio, you can learn how to build and run your app from
the command line. The output of the build is the same whether you are
building a project from the command line, on a remote machine, or using
Android Studio.
Gradle和Android插件独立于Android Studio运行。这意味着您可以在Android Studio、您机器上的命令行或未安装 android studio 的机器(如持续集成服务器)上构建您的Android应用程序。如果您没有使用Android Studio,可以从命令行学习如何构建和运行应用程序。无论您是从命令行、在远程计算机上还是使用Android Studio生成项目,生成的输出都是相同的。
The build process involves many tools and processes that convert your
project into an Android Application Package (APK). The build process is
very flexible, so it's useful to understand some of what is happening
under the hood.
构建过程涉及许多工具和过程,这些工具和过程会将您的项目转换为Android应用程序包(APK)。构建过程非常灵活,因此了解一些实际情况很有用。
Figure 1. The build process of a typical Android app module.
图1.典型的Android应用模块的构建过程。
The build process for a typical Android app module, as shown in figure
1, follows these general steps:
1. The compilers convert your source code into DEX (Dalvik Executable)
files, which include the bytecode that runs on Android devices, and
everything else into compiled resources.
2.The APK Packager combines the DEX files and compiled resources into a
single APK. Before your app can be installed and deployed onto an
Android device, however, the APK must be signed.
3.The APK Packager signs your APK using either the debug or release
keystore:
a. If you are building a debug version of your app, that is, an app
you intend only for testing and profiling, the packager signs your
app with the debug keystore. Android Studio automatically configures
new projects with a debug keystore.
b. If you are building a release version of your app that you intend
to release externally, the packager signs your app with the release
keystore. To create a release keystore, read about signing your app
in Android Studio.
4.Before generating your final APK, the packager uses the zipalign tool to optimize your app to use less memory when running on a device.
At the end of the build process, you have either a debug APK or release
APK of your app that you can use to deploy, test, or release to external
users.
如图1所示,一个典型的Android应用程序模块的构建过程遵循以下一般步骤:
编译器将您的源代码转换为DEX(Dalvik可执行文件)文件,其中包括在Android设备上运行的字节码,以及所有其他内容都转换为已编译资源。
APK打包器将DEX文件和已编译的资源合并到一个APK中。但是,必须先对APK签名,然后才能将您的应用安装和部署到Android设备上。
APK打包器使用调试或发布密钥库对您的APK进行签名:
a. 如果您正在构建应用程序的调试版本,即仅打算进行测试和性能分析的应用程序,则打包程序将使用调试密钥库对应用程序进行签名。Android Studio使用调试密钥库自动配置新项目。
b. 如果您要构建要从外部发布的应用程序的发行版本,则打包程序将使用发行密钥库对应用程序进行签名。
在生成最终APK之前,打包程序会使用zipalign工具优化您的应用,以在设备上运行时使用更少的内存。
在构建过程结束时,您可以拥有应用程序的调试APK或发布APK,可用于部署,测试或发布给外部用户。
Gradle 和 Android 插件独立于 Android Studio 运行。所以我们可以在 Android Studio上或者计算机上的命令行构建 Android 应用。 如果您不使用 Android Studio,可以学习如何从命令行构建和运行您的应用,最终构建的输出都相同。
APK (Android Package)文件,是一个后缀名为.apk的压缩文件,APK文件中包含了一个Android应用程序的所有内容,是Android平台用于安装应用程序的文件。APK就是一个zip压缩包,解开这个APK包我们可以看到以下的结构:
存放需要打包到APK中的静态文件,assets和res的区别如下,assets目录支持任意深度的子目录,用户可以根据自己的需求任意部署文件夹架构,而且res目录下的文件会在.R文件中生成对应的资源ID,assets不会自动生成对应的ID,访问的时候需要AssetManager类。
是resource的缩写,存放资源文件,存在这个文件夹下的所有文件都会映射到Android工程的.R文件中,生成对应的ID,访问的时候直接使用资源ID,即R.id.filename。
res 文件夹下可以包含多个文件夹,其中
anim
存放动画文件;drawable
目录存放图像资源;layout
目录存放布局文件;values
目录存放一些特征值,colors.xml
存放color颜色值,dimens.xml
定义尺寸值,string.xml
定义字符串的值,styles.xml
定义样式对象;xml
文件夹存放任意xml文件,在运行时可以通过Resources.getXML()读取;raw
是可以直接复制到设备中的任意文件,他们无需编译。存放应用程序依赖的native库文件,一般是用C/C++编写,这里的lib库可能包含4中不同类型,根据CPU型号的不同,大体可以分为ARM
,ARM-v7a
,MIPS
,X86
,分别对应着ARM架构,ARM-V7架构,MIPS架构和X86架构。
不同的CPU架构对应着不同的目录,每个目录中可以放很多对应版本的so库,且这个目录的结构固定,用户只能按照这个目录存放自己的so库。目前市场上使用的移动终端大多是基于ARM或者ARM-V7a架构的,X86和MIPS架构的移动智能终端比较少,所以有些应用程序lib目录下只包含armeabi目录或者armeabi-v7a目录。
保存应用的签名信息,签名信息可以验证APK文件的完整性。AndroidSDK在打包APK时会计算APK包中所有文件的完整性,并且把这些完整性保存到META-INF文件夹下,应用程序在安装的时候首先会根据META-INF文件夹校验APK的完整性,这样就可以保证APK中的每一个文件都不能被篡改。以此来确保APK应用程序不被恶意修改或者病毒感染,有利于确保Android应用的完整性和系统的安全性。
META-INF目录下包含的文件有CERT.RSA
,CERT.DSA
,CERT.SF
和MANIFEST.MF
,其中CERT.RSA是开发者利用私钥对APK进行签名的签名文件,CERT.SF、MANIFEST.MF记录了文件中文件的SHA-1哈希值。
是Android应用程序的配置文件,是一个用来描述Android应用“整体资讯”的设定文件,简单来说,相当于Android应用向Android系统“自我介绍”的配置文件,Android系统可以根据这个“自我介绍”完整地了解APK应用程序的资讯,每个Android应用程序都必须包含一个AndroidManifest.xml文件,且它的名字是固定的,不能修改。
我们在开发Android应用程序的时候,一般都把代码中的每一个Activity,Service,Provider和Receiver在AndroidManifest.xml中注册,只有这样系统才能启动对应的组件,另外这个文件还包含一些权限声明以及使用的SDK版本信息等等。
程序打包时,会把AndroidManifest.xml进行简单的编译,便于Android系统识别,编译之后的格式是AXML格式,如下图所示:
axml头:是固定标识axml文件的,其值固定是0x00080003。
axml文件长度:标识axml文件的大小。
StringDataSegment:xml文件中所有字符串类型保存在此。
ResourceIdSegment:xml文件中声明的资源文件ID保存于此。
XmlContentSegment:是xml的内容段,按照xml文件中的结构依次排开,保存xml的数据内容。
传统的Java程序,首先先把Java文件编译成class文件,字节码都保存在了class文件中,Java虚拟机可以通过解释执行这些class文件。
而Dalvik虚拟机是在Java虚拟机进行了优化,执行的是Dalvik字节码,而这些Dalvik字节码是由Java字节码转换而来,一般情况下,Android应用在打包时通过AndroidSDK中的dx工具将Java字节码转换为Dalvik字节码。
dx工具可以对多个class文件进行合并,重组,优化,可以达到减小体积,缩短运行时间的目的。dx工具的转换过程,如下图所示:
如上图所示,dx工具把每个.class文件的每个区域的内容进行去重,重组,优化重排后生成dex文件,生成的dex文件可以在Dalvik虚拟机执行,且速度比较快。
用来记录资源文件和资源ID之间的映射关系,用来根据资源ID寻找资源。
Android的开发是分模块的,res目录专门用来存放资源文件,当在代码中需要调用资源文件时,只需要调用findviewbyId()就可以得到资源文件,每当在res文件夹下放一个文件,aapt就会自动生成对应的ID保存在.R文件,我们调用这个ID就可以,但是只有这个ID还不够,.R文件只是保证编译程序不报错,实际上在程序运行时,系统要根据ID去寻找对应的资源路径,而resources.arsc文件就是用来记录这些ID和资源文件位置对应关系的文件。
aapt.exe工具(The Android Asset Packaing Tool),位于android-sdk/platform-tools目录下。
R.java
、resources.arsc
和 res
文件,res文件分为 二进制 和 非二进制 文件,典型的非二进制文件如:res/raw和图片,它们保持原样,不被编译。XML
文件保存在res/animator
目录下,用来描述属性动画
。XML
文件保存在res/anim
目录下,用来描述补间动画
。XML
文件保存在res/color
目录下,用描述对象颜色状态选择。XML
或者Bitmap
文件保存在res/drawable
目录下,用来描述可绘制对象。例如,我们可以在里面放置一些图片(.png, .9.png, .jpg, .gif),来作为程序界面视图的背景图。注意,保存在这个目录中的Bitmap文件在打包的过程中,可能会被优化的。例如,一个不需要多于256色的真彩色PNG文件可能会被转换成一个只有8位调色板的PNG面板,这样就可以无损地压缩图片,以减少图片所占用的内存资源。XML
文件保存在res/layout
目录下,用来描述应用程序界面布局。XML
文件保存在res/menu
目录下,用来描述应用程序菜单。任意格式
的文件保存在res/raw
目录下,它们和assets类资源一样,都是原装不动地打包在apk文件中的,不过它们会被赋予资源ID,这样我们就可以在程序中通过ID来访问它们。例如,假设在res/raw目录下有一个名称为filename的文件,并且它在编译的过程,被赋予的资源ID为R.raw.filename,那么就可以使用以下代码来访问它:Resources res = getResources(); InputStream is = res .openRawResource(R.raw.filename);
XML
文件保存在res/values
目录下,用来描述一些简单值,例如,数组、颜色、尺寸、字符串和样式值等,一般来说,这六种不同的值分别保存在名称为arrays.xml、colors.xml、dimens.xml、strings.xml和styles.xml文件中。XML
文件保存在res/xml
目录下,一般就是用来描述应用程序的配置信息。public static final int
类型成员。R.id.text_input_password_toggle
、R.drawable.shadow_left
。这一过程中使用到的工具是aidl.exe,位于android-sdk/platform-tools目录下。
AIDL (Android Interface Definition Language), Android接口定义语言,Android提供的IPC (Inter Process Communication,进程间通信)的一种独特实现。
这个阶段处理.aidl文件,生成对应的.java文件。如果在项目没有使用到aidl文件,则可以跳过这一步。
通过Java Compiler 编译项目中所有的Java代码,包括R.java、.aidl文件生成的.java文件、Java源文件,生成.class文件。
dx工具位于android-sdk/platform-tools 目录下,通过它生成可供Android系统Dalvik虚拟机执行的classes.dex文件。
在这个阶段任何第三方的libraries和.class文件都会被转换成.dex文件。
dx工具的主要工作是将Java字节码转成成Dalvik字节码、压缩常量池、消除冗余信息等。
打包的工具apkbuilder位于 android-sdk/tools目录下。apkbuilder为一个脚本文件,实际调用的是android-sdk/tools/lib/sdklib.jar文件中的com.android.sdklib.build.ApkbuilderMain类。
所有没有编译的资源(如 res/raw、images等)、Other Resources(assets文件)、编译过的资源 、.dex文件 、resources.arsc 和 AndroidManifest.xml 都会被apkbuilder工具打包到最终的.apk文件中。
注意:
res/raw和assets的相同点:两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。
res/raw和assets的不同点:
1.res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
2.res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹
一旦apk文件生成,它必须被签名才能被安装在设备上。
在开发过程中,主要用到的就是两种签名的keystore。一种是用于调试的debug.keystore,它主要用于调试。另一种就是用于发布正式版本的keystore。
如果你发布的apk是正式版的话,就必须对APK进行对齐处理,用到的工具是zipalign,它位于android-sdk/tools目录下。
Zipalign是一个android平台上整理APK文件的工具,它对apk中未压缩的数据进行4字节对齐,对齐的主要过程是将APK包中所有的资源文件距离文件起始偏移为4字节整数倍,对齐后就可以使用mmap函数读取文件,可以像读取内存一样对普通文件进行操作。如果没有4字节对齐,就必须显式的读取,这样比较缓慢并且会耗费额外的内存。
Adroid的应用安装涉及到如下几个目录:
具体安装过程如下:
APK安装的时候会把DEX文件解压并且优化位odex,odex的格式如下图所示:
如上图所示,odex在原来的dex文件头添加了一些数据,在文件尾部添加了程序运行时需要的依赖库和辅助数据,使得程序运行速度更快。