3

Goal

I want the libs present in my APK to be available on my device from a fixed location when I install my APK.

I opened another question about this issue based on my existing project. This time, I started a brand new project from scratch in order to reduce the unknowns and make my question simpler to resolve.

Steps I followed

With Android Studio 4.0.1, I do the following:

  • Start a new Android Studio project

  • Select Native C++

  • Set project name to test

  • Select Java as language

  • Use default toolchain

  • Build -> Make Project

Under the project view, I verify that my app-debug.apk has a lib folder containing a few subdirectories, each with at least the libnative-lib.so that was built for this project accordingly to the default CMakeLists.txt rules.

I would like this .so to be accessible from my device when I install my APK (I have a more complex project in which I create .so that I want accessible from outside the APK).

However, from my project folder, when I run:

c:\Users\xxx\AndroidStudioProjects\test>adb install app\build\outputs\apk\debug\app-debug.apk
Performing Streamed Install
Success

c:\Users\xxx\AndroidStudioProjects\test>adb shell ls /data/data/com.example.test
cache
code_cache

Other changes I tried

None of the following further changes allowed me to see additional files under /data/data/com.example.test

  • Added android.bundle.enableUncompressedNativeLibs=false to gradle.properties

  • Added

    android {
        ...
        sourceSets.main {
            jniLibs.srcDirs = ['libs']
            jni.srcDirs = []
        }
    

    to build.gradle do not change anything to this.

  • Added set(distribution_DIR ${CMAKE_SOURCE_DIR}/libs) to CMakeLists.txt

Lolo
  • 3,935
  • 5
  • 40
  • 50
  • I have root access. First link is about packaging the .so in the APK. In my case, my libs are already in the APK. Second link is my own question. Third link is about an external lib to the project. Here I am only concerned with making the .so of my own project available on device from a known location when installing the APK. – Lolo Jan 12 '21 at 13:39

1 Answers1

4

Native libraries are not placed in /data/data/your.app but in /data/app/your.aapp-<key-hash>==/lib/<ABI>, for example on my target:

hikey960:/ # cd /data/app/com.example.dlopen-6BSPeAN9VvjFlCxIzLHX9A\=\=/lib/arm64                                                                                     
hikey960:/data/app/com.example.dlopen-6BSPeAN9VvjFlCxIzLHX9A==/lib/arm64 # ls -als
total 1352
   4 drwxr-xr-x 2 system system    4096 2020-11-06 12:43 .
   4 drwxr-xr-x 3 system system    4096 2020-11-06 12:43 ..
1044 -rwxr-xr-x 1 system system 1067256 1981-01-01 01:01 libnative-lib.so
 300 -rwxr-xr-x 1 system system  305360 1981-01-01 01:01 libplugin.so

Also native libraries are archived by default and can not be accessible, for extracting them it is needed to set android:extractNativeLibs="true" in AndroidManifest.xml (for example like here: https://github.com/nkh-lab/ndk-dlopen/blob/master/dlopen/app/src/main/AndroidManifest.xml).

Mykola Khyliuk
  • 1,234
  • 1
  • 9
  • 16
  • 1
    Thanks. This is indeed what I observe and why I asked about a "fixed location". That hash is not practical as it changes each time and is difficult to predict short of searching the entire /data/app/ folder and select the folder that contains a string matching the package name. Isn't there a way to disable the hash? Also, I have other APKs that I install on the same device and that unpack the lib folder and its contents under /data/data/ so I was hoping I could just reproduce this behavior. – Lolo Jan 12 '21 at 13:36
  • But I guess these others APK in any case were installed into ```data/app/your.aapp-==/lib/``` but after that they just copy or create corresponding stuff in theirs internal storage ```data/data/your.aapp```. You can also try to copy your libraries from installed directory to internal storage during app first run. – Mykola Khyliuk Jan 12 '21 at 14:04
  • Yes, these other APK are also installed under /data/app. " You can also try to copy your libraries from installed directory to internal storage during app first run." That would definitely work for me BUT how would my app know the path to this /data/app//lib folder? Do you know how that path would be expressed in my app code in Java or in my native C? – Lolo Jan 12 '21 at 14:32
  • Here example how to get path of the native libraries form Java: https://github.com/nkh-lab/ndk-dlopen/blob/master/dlopen/app/src/main/java/com/example/dlopen/MainActivity.java#L30 – Mykola Khyliuk Jan 12 '21 at 14:37
  • After that you can provide it to native via JNI mechanism or for example via environment variable. – Mykola Khyliuk Jan 12 '21 at 14:38
  • Thank you. I verified this worked. This provides me a path forward. – Lolo Jan 12 '21 at 15:04