New project
Create a project with only one activity using Android Studio, not Using Android X or Kotlin, in order to experience the entire apK compilation process more easily.
Deleting Unnecessary Files
After deleting useless files, the following directories related to Gradle are deleted, because we do what Gradle does. I removed the theme file (theme.xml) and used FrameLayout for layout instead of constraint layout because the older version of AS will automatically use constraint layout for you.
Compile resource
Use aapT2 tools to compile the resources and go to the SRC directory of the project. Since you need to compile the entire RES resource file directory, you end up packing all the resources into a.zip file
$ANDROID_HOME/build-tools/29.0.3/ aapT2 compile --dir main/ res-o build/resources.zipCopy the code
Finally, if you unzip resource. Zip, you can see that all resources are compiled into a.flat file
Links to resources
Link syntax is as follows
aapt2 link path-to-input-files [options] -o
outputdirectory/outputfilename.apk --manifest AndroidManifest.xml
Copy the code
During the linking phase, AAPT2 merge all the intermediate files (.flat files) generated during the compilation phase and package them into ZIP packages (the prototype of the final APK cannot be installed properly because it does not include the DEX file and is not signed).
Here is the link command to enter the project’s SRC directory
$ANDROID_HOME/ build - the tools / 29.0.3 aapt2 link build/resources. The zip - I$ANDROID_HOME/platforms/android-30/android.jar --manifest main/AndroidManifest.xml -o build/out.apk
Copy the code
Parameter Description:
- I: Provide platform android.jar or other APK (e.g
framework-res.apk
), which can be useful when building functionality. If you want to use with in a resource fileandroid
Namespaces (for exampleandroid:id
), thenMust beUse this tag. - –manifest: Specifies the AndroidManifest file, which contains packagename and Application ID
- -o: specifies the output directory and apK file
You get an APK, out.apk. If you unzip the APK, you can see that it is a pure resource APK.
Compile Java source files
Since it is an Android project and references R files, we need to create R files, so we directly generate R files in the original Java file location, into the SRC directory
$ANDROID_HOME/build-tools/29.0.3/aapt package -f -m -j main/ Java -m main/ androidmanifest.xml -s main/res -i$ANDROID_HOME/platforms/android-30/android.jar
Copy the code
-f forces the existing file to be overwritten. -m Specifies the full path of the androidmanifest.xml file contained in the zip. -s specifies the directory in which to look for resources. Multiple directories are scanned, and the first match found (from left to right) takes precedence. -i adds an existing package to the basic inclusion set. -j specifies the output location defined by the R.Java resource constant
Go to the Java files directory and compile MainActivty and R files
Javac -encoding UTF-8 - Target 1.8 mainactivity. Java r.java-bootclasspath$ANDROID_HOME/platforms/android-30/android.jar
Copy the code
Turn the class dex
Go to the SRC directory of the project
$ANDROID_HOME/ build - the tools / 29.0.3 / d8 main/Java/net/mikaelzero/gradledemo / *. The class - the classpath$ANDROID_HOME/platforms/android-30/android.jar --output /build
Copy the code
Get a classes.dex
integration
Now you have out.apk, which is the pure resource apk and classes.dex files, in your build
zip -ur out.apk classes.dex
Copy the code
Dex files can be found and integrated into APK through decompression. In fact, after decompressing out.apk, dex is put in and compressed again.
The signature
I created a JKS from AS and put it in the build directory
$ANDROID_HOME/build-tools/29.0.3/apksigner sign --ks build/gradle-key_store.jks /build/out.apk
Copy the code
After signing, you get a complete APK, which is installed via ADB Install, as shown in the screenshot below
aar
Download a RecyclerView aar after decompression as follows:
The AAR file has a.aar file extension, and the Maven artifact type should also be AAR. The file itself is a ZIP file. The only required entry is/androidmanifest.xml. In addition, an AAR file may contain one or more of the following optional entries:
/classes.jar
/res/
/R.txt
/public.txt
/assets/
/libs/name.jar
/jni/abi_name/name.so
Abi_name is AndroidSupport the ABIOne of the)/proguard.txt
/lint.jar
/api.jar
/prefab/
(forExporting native libraries)
How is an AAR used
A local use
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
compile(name:'AAR-name'.ext:'aar')}Copy the code
A remote use
dependencies {
implementation 'androidx. Appcompat: appcompat: 1.2.0'
}
Copy the code
- For remote dependencies, Gradle downloads the corresponding POM file and then downloads the AAR file according to the POM file configuration
- Through the transformer to aar is converted to a classes. The jar, the transformed result cache, general path is ~ /. Gradle/caches/transforms – 2 or ~ /. Gradle/caches/transforms – 1
- The transformed artifacts are obtained by ConfigurationContainer
Try using an AAR in your own APK
Generated aar
Create a new Module with Android Studio, then grab the AAR file, put it in the build directory of the project, and go to the Build directory
Compile aar resource files
$ANDROID_HOME/build-tools/29.0.3/ aapT2 compile --zip mylibrary-debug.aar -o resources_module.zipCopy the code
The –zip parameter will traverse all aar internal files and identify resource files for compilation
Then compile the resources for the main project
$ANDROID_HOME/build-tools/29.0.3/ aapT2 compile --dir main/ res-o build/resources.zipCopy the code
You get two zip files, as follows
link
Since there are multiple androidmanifest.xml files, the first step is to perform a merge operation on androidmanifest.xml. There is no tool for merging manifest files, so you need to merge them manually
Then link to the SRC directory
$ANDROID_HOME/build-tools/29.0.3/ AAPT2 link build/resources_module.zip build/resources_module.zip -i$ANDROID_HOME/platforms/android-30/android.jar -o build/out_merge.apk --extra-packages net.mikaelzero.mylibrary --manifest main/AndroidManifest.xml -v --java build/
Copy the code
–extra-packages package_name Generates the same R.java file with a different package name. The purpose is to regenerate R files for aar, because AAR does not carry R files. — Java **directory ** specifies the directory in which R.Java will be generated. In this case, the generation must be performed at the same time. Otherwise, ID conflicts will occur. After the generation, manually copy the data to the corresponding Java directory.
Why not bring the R file? The ID in the R file is unique, which may conflict in the case of a large number of AAR references. Therefore, **** revives all resource ids in the process of merging aar into APK, making the R globally unique in the app.** You can also find in your own projects that there are a lot of R files
Combine the two resource files generated at compile time into out_merge.apk. When you unzip the app, you can see that the resources are merged together
Compile the source code
The source code needs to be modified,The main thing is to add a jump. The Activity of the jump comes from the AAR, so when compiling, you need to link the AAR jar package
Javac - encoding utf-8-1.8 main target/Java/net/mikaelzero/gradledemo / *. Java build/mylibrary/src/main/java/net/mikaelzero/mylibrary/*.java -bootclasspath$ANDROID_HOME/platforms/android-30/android.jar; build/classes.jarCopy the code
Turn the class dex
$ANDROID_HOME/ build - the tools / 29.0.3 / d8 main/Java/net/mikaelzero/gradledemo / *. Class build/mylibrary/src/main/java/net/mikaelzero/mylibrary/*.class --classpath$ANDROID_HOME/platforms/android-30/android.jar --output build
Copy the code
The build directory now has a classes.dex file that looks like this
integration
Go to the build directory
zip -ur out_merge.apk classes.dex
Copy the code
The signature
$ANDROID_HOME/build-tools/29.0.3/apksigner sign --ks gradle-key_store.jks out_merge.apk
Copy the code
After installing with the ADB command, you’ll notice a jump to TestActivity