preface
- This is the first article in the Android 10 source code analysis series
- Branches: android – 10.0.0 _r14
- Read the full text for about 10 minutes
Outputs /outputs/ apK to build/outputs/ apK files that can be installed on Android devices.
The APK file can be divided into two parts: code and resources, so the package is also divided into two parts: code and resources. We can understand the construction process of an APK according to the flow chart provided by Google
New Build Flowchart
The content of APK package mainly includes: application module, which is the source code, resource file and AIDL interface file developed by oneself, and dependent module, which is the third-party dependent library used by source code, such as AAR, JAR and SO file
To get a clear idea of how APK is generated, take a look at the old build flowchart
Old build flowchart
Before we look at the APK generation process, we need to understand the role of the tools shown below
tool
The name | function |
---|---|
AAPT/APT2 | Android resource packaging tool |
AIDL | Convert all AIDL interfaces to Java interfaces |
Javac(Java Compiler) | Compile all Java code into Class files |
Dex | Compile the Class file into a Dex file |
Apkbuilder | The processed resources and code are packaged to generate APK files |
Jarsigner/Apksigner | Sign an unsigned APK file |
Zipalign | Optimize signed APK to reduce memory footprint at run time |
The build process
1. Use AAPT to generate r.Java files
AAPT (Android Asset Packaging Tool) is an Android resource Packaging Tool that packages resource files (including androidmanifest.xml, layout files, and various XML resources) to generate R.Java files. Androidmanifest.xml generates a binary Androidmanifest.java file
Aapt p -m androidmanifest.xml -s output/res/ -i android.jar -j./ -f input/out.apk p: package -m: androidmanifest.xml file path -s: Res directory path -a: assets directory path -I: android.jar directory, which will be used by some system libraries -j specifies the generated output directory of R. Java. -f specifies the output of APK filesCopy the code
Since Android Studio 3.0, However, Google has enabled AAPT2 as a compiler for resource compilation by default. AAPT2 provides support for incremental compilation of resources. AAPT2 consists of two main steps, compile and link
compile
Aapt2 compile -o res.apk --dir output/res/ -o: specifies the output path of compiled resources. --dir: specifies the resource directory that contains multiple resource filesCopy the code
link
Aapt2 link - o input/out apk -i tools/android. The jar - manifest the output/AndroidManifest. XML - A res. Apk -- Java. / -o: Specify the output path of the linked resource APK -i: specify the android.jar path --manifest: specify the androidmanifest.xml path -- Java: specify the directory in which R.java is generatedCopy the code
2. All AIDL interfaces are converted to Java interfaces
Android Interface Denifition Language (AIDL), located in the SDK \build-tools directory AIDL, Generate Java files from source files, aiDL files, framework.aidl and other AIDL files as follows:
aidl -Iaidl -pAndroid/Sdk/platforms/android-29/framework.aidl -obuild Aidl/com/android/vending/billing/IInAppBillingService aidl -i specify the import statement search path, -p specifies the import statement path of the system class. If you want to use the android.os.Bundle system class, you must set the framework. Note that there must be no Spaces between -o and the directory, and that this setting must be set before the aiDL file pathCopy the code
3. Compile the Java code into a Class file
Use Javac (Java Compiler) to compile all Java code in the project into class files, including Java source files, R.java files generated by AAPT, and Java interface files generated by AIDL, using the following command:
Javac-target 1.6 -bootclasspath platforms/android-28/android.jar -d./ Java /com/testjni/*.javaCopy the code
4. Compile the Class file into a Dex file
Use the DX tool to convert all Class files (including Class files in third-party libraries) into Dex files (Dalvik executables, including bytecode running on Android devices). This process mainly completes the conversion of Java bytecode to Dalvik bytecode. The command is as follows:
Java -jar dx. Jar --dex --ouput= class.dex./ Java /com/testjni/*Copy the code
5. Package and generate APK files
Use Apkbuilder (mainly using the ApkBuilderMain class in the SDK /tools/lib/sdklib.jar file) to put all the Dex files, Resource Package folder, Androidmanifest.xml to generate APK file (unsigned)
6. Sign the APK file
Use Apksigner or Jarsigner to sign unsigned APK files
Ps: if you use Apksigner signature need (7. Signing APK files) before signing, why? Please refer to the differences between Apksigner and Jarsigner at the end of this article
7. Optimize APK files
Use Zipalign to align signed APK files. The main process of alignment is to offset all resource files in the APK package to an integer multiple of 4 bytes from the start of the file. In this way, APK files can be accessed faster through memory mapping and the memory occupied by APK files can be reduced when running on the device
conclusion
AndroidStudio builds the package automatically by calling various build commands.
- Except for assets and RES/RAW resources, which are packaged into APK unchanged, all other resources are compiled or processed
- All assets except assets are given a resource ID
- The packaging tool compiles and packages resources. Once compiled, it generates a resources.arsc file, which holds a resource index table, and an R.java, which defines the resource ID constants
- The application configuration file Androidmanifest.xml is also compiled into binary XML files and packaged into APK
- Applications access resources at run time through AssetManager, by resource ID, or by file name
APK files can be divided into two parts: code and resources. The code part compiles the Java code into a Class file through Javac, and then compiles the Class file into a Dex file through DX tool. Next, we mainly analyze the compilation and packaging of resources
Compilation and packaging of resources
Before analyzing the compilation and packaging of resources, we need to know what resources Android has. In fact, Android resources are roughly divided into two parts: Assets and RES
1. Assets and resources
Assets are stored in the Assets directory, which contains some original files that can be organized in any way. These files are eventually packaged intact into APK files and retrieved from AssetManager, as shown below
AssetManager assetManager = context.getAssets();
InputStream is = assetManager.open("fileName");
Copy the code
2. Res
Res resources are stored in the RES directory of the main project. These resources generally generate a resource ID for us to use during compilation. Res directories include animator, Anim, Color, Drawable, Layout, Menu, RAW, Values, XML, etc
All the preceding resource files are compiled into binary XML files except raw resources and bitmaps in the Drawable folder. The binary XML files have a string resource pool, which is used to store each string referenced in the file
Each place where a string is placed in a text XML file is replaced in a binary XML file with an integer value indexed to the string resource pool. The integer value is stored in the R.Java class, which is compiled into APK along with other source files
Compiling resources into binary files is accomplished by AAPT tool. Resource packaging mainly includes the following processes:
- Parse androidmanifest.xml to get the package name for the application and create the resource table
- To add a referenced resource bundle, the added resource is defined in R.Java as a resource ID
- The resource packaging tool creates an AaptAssets object and collects the resource files that need to be compiled. The collected resources are stored in the AaptAssets object
- Add the resources saved in the previous AaptAssets object to the ResourceTable ResourceTable to generate the resource description file resources.arsc
- Compiles values class resources that include arrays, colors, sizes, and string equivalents
- Assign resource ids to resources such as style and array
- The process of compiling XML resource files is divided into: ① Parsing XML files ② assigning attribute names and resource IDS ③ parsing attribute values ④ Converting XML files from text format to binary format
- Generate the resource index table resources.arsc
2.1 resource ID
The AAP tool generates an R.Java file for all resources, and each resource corresponds to an r.Java hexadecimal integer variable. These hexadecimal integers are composed of three parts: PackageId + TypeId + ItemValue.
public final class R { public static final class anim { public static final int abc_fade_in=0x7f010000; public static final int abc_fade_in=0x7f010001; //*** } public static final class string { public static final int a11y_no_data=0x7f100000; public static final int a11y_no_permission=0x7f100001; / / * * *}}Copy the code
The highest byte is the Package ID that represents the namespace and identifies the source of the resource. The Android system defines two Package ids: system resource namespace 0x01 and application resource namespace 0x7f
Because of the resource namespace 0x7f, we have a problem when we do the plug-in. The host and the plug-in package merge the resource and the resource ID conflicts. The solution to this problem is to set different packageids for different plug-ins, and the host can leave the original 0x7f unchanged, so that no conflicts will ever occur
How to resolve resource conflicts
- Develop a naming convention that doesn’t conflict
- Set resource prefixes in build.gradle of library Module (recommended)
Android {resourcePrefix "< prefix >"}Copy the code
2.2 Resource Index (Resources.arSC)
Arsc is a compiled binary file. Open the resources. Arsc file in AndroidStudio, as shown below
Android uses this index table to search resources according to resource IDS, providing the best resources for different languages, different regions and different devices. Find and do it through Resources and AssetManger
Two tools Apksigner and Jarsigner are mentioned in the article. The following are the differences between Apksigner and Jarsigner
Difference between Apksigner and Jarsigner
In Android Studio, click on Build->Generate signed APk… During the packaging process, you can see two Signature options V1(Jar Signature) and V2(Full APK Signature).
- Jarsigner is a generic tool provided by the JDK for signing JAR packages
- Apksigner is a special tool for Android APK signature and authentication provided by Google
For Android 7.0, Google has added a new Signature Scheme V2 (APK Signature), but for Android 7.0 and later, you can only use the old Signature Scheme V1 (JAR signing).
V1(Jar Signature)
From the JDK(Jarsigner), verify each file of the ZIP package, and modify (move/recompress files) the ZIP package after signing. Unzip V1 signature APK/JAR, store signature files in meta-INF (manifest. MF, cert. SF, cert. RSA), The manifest.mf file stores the SHA1 fingerprint of all files (except meta-INF files). V1 signature is used to verify the signature of a single file in the compressed package
V2(Full APK Signature)
The signature file (including zipalign) cannot be modified after the signature. The signature file (including zipalign) cannot be modified after the signature file (including zipalign) is decompressed. The signature file (including zipalign) of V2 signature is not found. The V2 signature validates the entire APK signature
To create a publishing keystore, see Signing an application in Android Studio
conclusion
- V1 signature verifies the signature of a single file in the compressed package
- The V2 signature validates the entire APK signature
- Zipalign can be executed after V1 signature
- Zipalign cannot be executed after V2 signature, but only before V2 signature
- V2 signature more secure (cannot modify compressed package)
- V2 signature verification takes less time (no decompression is required), speeding up the installation
Note: The apkSigner tool uses both V1 and V2 signatures by default to be compatible with Android versions below 7.0
reference
- Google’s Apk build process
- Sign applications in Android Studio
- AAPT2
conclusion
Dedicated to share a series of Android system source code, reverse analysis, algorithm, translation, Jetpack source code related articles, is trying to write a better article, if this article is helpful to you to give a star, what is not written in the article clearly, or have better advice, welcome to leave a message, welcome to learn together, Moving forward together on the technological road.
Plan to establish a most complete and latest AndroidX Jetpack related components of the actual combat project and related components of the principle of analysis article, is gradually increasing Jetpack new members, the warehouse continues to update, you can go to check: Androidx-jetpack-practice, if this warehouse is helpful to you, please give me a thumbs up and I will finish more project practices for new members of Jetpack one after another.
algorithm
Since LeetCode has a large question bank, hundreds of questions can be selected for each category. Due to the limited energy of each person, it is impossible to brush all the questions. Therefore, I sorted the questions according to the classic types and the difficulty of the questions.
- Data structures: arrays, stacks, queues, strings, linked lists, trees…
- Algorithms: Search algorithm, search algorithm, bit operation, sorting, mathematics,…
Each problem will be implemented in Java and Kotlin, and each problem has its own solution ideas, time complexity and space complexity. If you like algorithms and LeetCode like me, you can pay attention to my LeetCode problem solution on GitHub: Leetcode-Solutions-with-Java-And-Kotlin, come to learn together And look forward to growing with you.
Android 10 source code series
I’m writing a series of Android 10 source code analysis articles. Knowing the system source code is not only helpful in analyzing problems, but also very helpful in the interview process. If you like to study Android source code as MUCH as I do, You can follow my Android10-source-Analysis on GitHub, and all articles will be synchronized to this repository.
- How is APK generated
- APK installation process
- 0xA03 Android 10 source code analysis: APK loading process of resource loading
- Android 10 source code: APK
- Dialog loading and drawing process and use in Kotlin, DataBinding
- More……
Tool series
- Shortcuts to AndroidStudio that few people know
- Shortcuts to AndroidStudio that few people know
- All you need to know about ADB commands
- How to get video screenshots efficiently
- 10 minutes introduction to Shell scripting
- How to package Kotlin + Android Databinding in your project
The reverse series
- Dynamically debug APP based on Smali file Android Studio
- The Android Device Monitor tool cannot be found in Android Studio 3.2