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 thejava/com/min/helloapk/MainActivity.javafile

Manifest

  • Modify theAndroidManifest.xmlfile

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