Search code examples
javaandroidandroid-ndkjava-native-interfaceaapt

How does the content of lib end up in a Android *.apk file?


Android App apk-files are actually zips. Using (JNI), i.e. native code means to add *.so files to your apk. My question is how do they actually end up inside of the apk file?

I know so far that, looking at the example how such *.so are build and used from within the Java-code. What I do already know is how such files are eventually stored like this inside of the apk/zip archive:

res/
assets/
META-INF/
lib/
  |<arch1>
        |libSharedNativeLib1.so
        |libSharedNativeLib2.so
  |<arch2>
        |libSharedNativeLib1.so
        |libSharedNativeLib2.so
AndroidManifest.xml
classes.dex
resources.arsc

I know also how the entries classes.dex,AndroidManifest.xml,resources.arsc,assets,res and META-INFO are made. It is a succession of aapt, jarsigner. The only thing I have no idea is now the lib is put into the apk.

Background

I like to keep things simple. Using IDE such as Android Studio and Eclipse seems a nice way to shurtcut here, since they keep the users somewhat in the dark to what happens automagically in the background of the actual building process (being done with the help of various build-tools such as ANT, Maven, Grandle, Groovy...)

While there is nothing really bad about such tools, they tend to reduce the knowledge needed to pull of the trick of "building a apk", and consequently seem to reduce the documetation about a manual way to achieve the very same thing. It would help me much to know what Grandle actually does when the zip files end up in the apk/zip archive.

Right now I have tested and this seems to work

zip -r appfile.apk lib

and testing it seemed that upon installing the Android system actually really copied and linked into place the correct lib*.so native app's namely to

root@armdev:/data/data/name.package # ls -l
total 12
drwxr-x--x    2 10142  10142  4.0K .
drwxrwx--x  103 1000   1000   8.0K ..
lrwxrwxrwx    1 1012   1012   42 lib -> /data/app/name.package/lib/arm

Now one could assume that Androids pm install appfile.apk simply goes by looking for the lib folder structure inside of the apk/zip file and copies the lib*so files in place and symlinks them to /data/data/name.package/lib, but I would really like to know if there is more to it, not as to depend on being only lucky with the zip command above.

I have already tried aapt's -A (for assets) and -S (for resources) but neither worked to include the lib folder into the apk file via aapt.

, will end up packed into the apk-file within a folder lib//lib*.so

I want to develop some Android software ( *.apk file / an App ) and I do not use IDEs like Android Studio or Eclipse and neither Building Tools as Grandle, Maven, nor Ant....


Solution

  • Using zip is quite safe (until some breaking change is introduced in a future version of Android). You could work with aapt, but it does not accept the nice recursive flag. You can have a look at the system code that extracts the shared libraries. There is no magic, it opens the contents table of the ZIP (a.k.a. APK) file, and looks for files that match the supported ABI.