After I became an Android Developer, I was always curious about how a.apk file was generated and how it was changed from a pile of.java and.xml files to a.APk file. With the improvement of my knowledge system, this problem seems to be more and more clear, but I never really combed through the process. Happen to encounter relevant problem recently, take this opportunity to sum up, title its clothes, in order to remember its matter ~
Environment to prepare
- Mac OS
- Java
- Android SDK
Prepare project
Create a project
Create a new project using Android Studio, such as HelloAPK, and the resulting project should contain the following content:
[min@TATEMIN-MB0:] HelloAPK $ ls -al total 72 drwxr-xr-x 14 min staff 448 5 21 10:04 . drwxr-xr-x 33 min staff 1056 7 10 One.. -rw-r--r-- 1 min staff 208 5 21 10:04 .gitignore drwxr-xr-x 5 min staff 160 5 21 10:04 .gradle drwxr-xr-x 10 min staff 320 5 21 13:53 .idea -rw-r--r-- 1 min staff 862 5 21 10:04 HelloAPK.iml drwxr-xr-x 9 min staff 288 5 21 10:06 app -rw-r--r-- 1 min staff 564 5 21 10:04 build.gradle drwxr-xr-x 3 min staff 96 5 21 10:04 gradle -rw-r--r-- 1 min staff 1073 5 21 10:04 gradle.properties -rwxr--r-- 1 min staff 5296 5 21 10:04 gradlew -rw-r--r-- 1 min staff 2260 5 21 10:04 gradlew.bat -rw-r--r-- 1 min staff 432 5 21 10:04 local.properties -rw-r--r-- 1 min staff 43 5 21 10:04 settings.gradleCopy the code
However, it is the app/ SRC /main directory that determines the generation of the APK, so this directory is the workspace where we compile the APK.
Modify the project
We need to remove some non-frameWord dependencies on Android X from the project to make it as easy as possible. Details are as follows:
Resource file
-
Delete res/values/styles. XML;
-
Edit res/layout/activity_main.xml:
Code files
- Modify the
java/com/min/helloapk/MainActivity.java
file
Manifest
- Modify the
AndroidManifest.xml
file
Compile the project
-
To generate the signature
[min@TATEMIN-MB0:] main $ keytool -genkey -alias android.keystore -keyalg RSA -validity 1000 -keystore android.keystore Copy the code
-
See the signature
[min@TATEMIN-MB0:] main $ keytool -list -v -keystore android.keystore Copy the code
-
Generate R.j ava
[min@TATEMIN-MB0:] main $ aapt package -v -f -m -S res/ -J java/ -M AndroidManifest.xml -I /Users/min/Library/Android/sdk/platforms/android-26/android.jar Copy the code
-
Compile the code
[min@TATEMIN-MB0:] main $ mkdir gen Create an intermediate file directory [min@TATEMIN-MB0:] main $ javac java/com/min/helloapk/*.java -verbose -classpath $ANDROID_HOME/platforms/android-26/android.jar -d gen Copy the code
The following files are generated in the bin directory:
[min@TATEMIN-MB0:] main $├─ com ├─ ├─ R$attr.class ├ ─ ─ R$color.class ├ ─ ─ R$drawable.class ├ ─ ─ R$layout.class ├ ─ ─ R$mipmap.class ├ ─ ─ R$string.class └ ─ ─ R.c lassCopy the code
-
Creating a Dex File
[min@TATEMIN-MB0:] main $ mkdir bin [min@TATEMIN-MB0:] main $ dx --dex --verbose --output=bin/classes.dex gen Copy the code
The following files are generated in the bin directory:
[min@TATEMIN-MB0:] main $tree bin/ bin/ ├ ─ classes.dexCopy the code
-
Create an APK file
[min@TATEMIN-MB0:] main $ aapt package -v -f -M AndroidManifest.xml -S res -I $ANDROID_HOME/platforms/android-26/android.jar -F bin/HelloAPK.unsigned.apk bin Copy the code
The files in the bin directory are listed as follows:
[min@TATEMIN-MB0:] main $tree bin/ bin/ ├─ helloapk.unsigned.class.dexCopy the code
-
APK signature
[min@TATEMIN-MB0:] main $ jarsigner -verbose -keystore android.keystore -signedjar bin/HelloAPK.signed.apk bin/HelloAPK.unsigned.apk android.keystore Copy the code
-
zipalign APK
zipalign -v -f 4 bin/HelloAPK.signed.apk bin/HelloAPK.apk Copy the code
-
Install the APK
[min@TATEMIN-MB0:] main $ adb install bin/HelloAPK.apk Copy the code
-
Run the APK
The appendix
The following is the Workspace of the whole compilation project:
min@TATEMIN-MB0:] Main $tree ├── AndroidManifest.xml ├─ Android.keystore ├─ bin │ ├─ helloApk.apk │ ├─ │ ├─ gen │ ├─ com │ ├─ │ ├─ unsigned. │ ├─ gen │ ├─ MainActivity. Class │ ├ ─ ─ R$attr.class │ ├ ─ ─ R$color.class │ ├ ─ ─ R$drawable.class │ ├ ─ ─ R$layout.class │ ├ ─ ─ R$mipmap.class │ ├ ─ ─ R$string.class │ └ ─ ─ R.c lass ├ ─ ─ Java │ └ ─ ─ com │ └ ─ ─ min │ └ ─ ─ helloapk │ ├ ─ ─ MainActivity. Java │ └ ─ ─ R.j ava └ ─ ─ res ├ ─ ─ Drawable │ └ ─ ─ ic_launcher_background. XML ├ ─ ─ drawable - v24 │ └ ─ ─ ic_launcher_foreground. XML ├ ─ ─ layout │ └ ─ ─ Activity_main. XML ├ ─ ─ mipmap anydpi - v26 │ ├ ─ ─ ic_launcher. XML │ └ ─ ─ ic_launcher_round. XML ├ ─ ─ mipmap - hdpi │ ├ ─ ─ │ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├── ├─ ├── ├── ├── ── ── ── ── ── ── ── ── │ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├── ├─ ├── ├── ├── ── ── ── ── ── ── ── ── ── ── │ ├─ ├─ ├─ ├─ pastile.txt ├─ pastile.txt ├─ pastile.txt ├─ pastile.txt ├─ pastile.txt ├─ pastile.txt ├─ pastile.txt strings.xml 20 directories, 33 filesCopy the code