Building Android Application Bundles (APKs) by Hand

If you’ve ever tried to build an Android application package by hand, you might have gotten frustrated by the ‘comprehensive’ documentation, which states:

The other platform tools, such as aidl, aapt, dexdump, and dx, are typically called by the Android build tools or Android Development Tools (ADT), so you rarely need to invoke these tools directly. As a general rule, you should rely on the build tools or the ADT plugin to call them as needed.

That’s a perfectly reasonable suggestion for most applications but occasionally you need to get your hands dirty and do some plumbing yourself. If you find yourself in such a situation, below is a quick example of how to create an APK by hand.

Generate the R.java file

aapt package -m -J gen/ -M ./AndroidManifest.xml -S res1/ -S res2 ... -I android.jar

In somewhat plain English, that means:

  • -m instructs aapt to create directories under the location specified by -J, which is:
  • -J specifies where the output goes. Saying -J ./gen/ will create a file like ./gen/com/something/app/R.java
  • -S specifies what directory to spider to find your drawables, layouts, etc. You can specify this one more than once if you want to share resources among projects.
  • -I tells aapt where the android.jar is. You can find yours in a location like <android-sdk>/platforms/android-<API level>/android.jar

Compile your project

To build your application, I find the pre-generated build.xml files from either the Android toolset, from IntelliJ, Eclipse, etc, to be sufficient or easily adaptable, so I won’t dive into that here.

Process your classes for the Dalvik Virtual Machine (dex)

cd <the place where your compiled classes are> ; dx —dex —output=classes.dex SomeJar1.jar SomeJar2.jar …

The dx tool will recurse through your current directory and create the named output file. Just add onto the command line any extra jars you need to link in.

Create the initial APK package

Now we start to actually assemble everything:

aapt package -f -M ./AndroidManifest.xml -S res1/ -S res2/ ... -I android.jar -F MyProject.apk.unaligned

This command is very similar to the first invocation. The main difference is that here we are giving the -F flag, which tells aapt to build an APK file (contrast with the -J flag we provided above).

aapt add -f MyProject.apk.unaligned classes.dex

This one opens the existing APK made by the preceding command and adds all of our compiled binaries.

Sign the package

Generating a key is well documented and is beyond the scope of this post. Assuming you have a key in a keystore, you can invoke jarsigner to sign your key thusly:

jarsigner -storepass <keystore password> -keystore <keystore filename> MyProject.apk.unaligned <key name>

Aligning the APK

Aligning the contents of the APK can increase performance. An invocation would look like:

zipalign 4 MyProject.apk.unaligned MyProject.apk

Run it

At this point you should have a complete MyProject.apk that is ready to install.

Conversation
  • Aleq says:

    Thank you!

  • Comments are closed.