This article takes a macro look at the APK file structure and its design ideas, using a simple “Hello Android” as an example

APK file structure

An APK file contains all of a program’s code (such as .dex file), resources, assets, certificates, and manifest file.

The APK file itself is a compressed file, and we can compare the APK file with a simple Hello Android example and a complex application. First, create a simple Hello Android project, build an APK file and drag it to AS to open it with apKAnalyzer. The basic composition is shown in the figure below:

  1. Androidmanifest.xml: used to declare application package name information, related permissions, four components, Android SDK version, etc.
  2. Res directory: contains the main resource files of the program, including RES /layout, RES /drawable, mainly layout files and images and other resources. (wechat confuses resources with string clipping, as shown in the figure r=res);
  3. Resources. ars: resource mapping table containing a portion of compiled resources (res/ values) and resource paths that can be mapped to the corresponding resource file or value by the ID in resource R. Java;
  4. Assets directory: contains uncompressed original files, mainly some multimedia files or additional files.
  5. Lib directory: various. So link libraries used;
  6. Classes.dex: packaged application code, subcontracted for complex applications, containing multiple dex files (wechat);
  7. Meta-inf directory: contains APK signature information
    • Manifest.mf: MANIFEST file, a list of all files in the current APK and their hash values;
    • Cert. SF: Hash value for each message in the above manifest file;
    • Cert. RSA: digital signature of cert. SF file and digital certificate used for signature;

How are these files generated? Let’s look at the process of building an APK file.

APK packaging process

By default, Android Studio uses Gradle organization to complete the packaging process, which is easy for developers to execute related tasks. This transparent packaging process also makes us ignore many details. Here we take the APK file structure as a contrast, to see the source structure into the final APK file process.

1. AndroidManifest.xml

Taking Hello Android as an example, compare androidmanifest.xml in the source code with androidmanifest.xml in APK

Resource Packaging Process
aapt
aapt

2. res/

Comparing the source code with the changes in res directory after packaging, it can also be found that the drawable resources in RES have not changed significantly (in fact, it will be partially compressed), and the XML file under Layout/has undergone string replacement and compilation similar to androidmanifest.xml, and become binary files. And values/ is gone. The processing of res/ also occurs during aAPT compilation of resources, where XML files are compiled and string clipped, and part of the XML resources are compiled into resources.arsc.

3. resources.arsc

Resources. arsc is also a binary file, which is a product of aAPT’s process of packaging resources. The res/value file is compiled into resources.arsc, and the ids and paths of other resource files are also written into this file. Easy run-time access.

For those unfamiliar with resource packaging and access, see:

Android Resource Framework: Resource packaging process

Android Resource Framework: Runtime access to resources

4. assets/

The files in the directory are not changed

5. lib/

There is no change

6. Classes.dex

Dex files are Dalvik and ART executable formats. In contrast to the JVM, dex packages multiple class files together, so getting from a Java file to dex requires a Java –>class–>dex process.

  • If AIDL is used, use SDK /build-tools/ XXX/AIDL to parse AIDL files and generate corresponding Java files.
  • Compile all Java files to generate.class files;
  • Use the dx script to process all class files, including third-party Jar packages, into dex files. If multidex is configured, multiple classes.dex files may be generated. Dx and other related scripts are located in SDK /build-tools/ XXX /

Compared with class files, dx tool in the process of generating dex files, the character constant pool and some redundant information will be compressed, and the structure is more compact than class files.

Pack 7.

Use apkBuilder, which is also located in SDK /build-tools/, to package the relevant resource files after aAPT processing and the Classes. Dex generated by dx processing to generate APK files

8. Align the APK

Align APK files with zipalign:

Zipalign is an archive alignment tool that makes important optimizations for Android application files. The goal is to ensure that the beginning of all uncompressed data performs a specific alignment with respect to the beginning of the file. Specifically, it aligns all uncompressed data in APK (such as images or raw files) on 4-byte boundaries. This way, all parts can be accessed directly using mmap(), even if they contain binary data with alignment restrictions. This has the advantage of reducing the amount of RAM consumed when running your application.

9. The signature

Use apkSigner to sign the generated APK file.

At this point, we have a stand-alone APK file that contains code + resource + signature information.

The scripts and tools used above are located in SDK /build-tools/

conclusion

We first analyzed the components of a basic APK file, then disassembled the generation process of each component file and its associated scripts. If you are interested in the specific workflow of AAPT, DX, apksigner, you can find and read the source code. Look at the official packaging flow chart again, I believe you will be more clear!

Related reading:

Android MultiDex subcontracting and loading principle

Android Resource Framework: Resource packaging process

Android Resource Framework: Runtime access to resources