0

So I'm providing binaries as a remote dependency packaged as an aar. The android library has the libMyLibrary.so files in the src/main/jniLibs/<abi>/ directory, so when built and deployed they're in the aar's jni dir. The only other thing the library has is a manifest file containing nothing but the package name package.name.A

importing package.name.A as dependency on a different project, different.package.B, results in everything being packaged properly on the build and the shared libs are contained in the debug/release apk's lib/<abi>/libMyLibrary.so. They're not being extracted to the application's native directory upon install though.

The actual installed apk shows that the .so files are there in the apk ZipFile(context.applicationInfo.sourceDir).getEntry("lib/${Build.SUPPORTED_ABIS[0]}/libMyLibrary.so") works and I can extract it that way (just not to the application's nativeDir, security exception). And System.mapLibraryName("MyLibrary") returns "libMyLibrary.so"...

They were being extracted before I supplied them as a remote dependency, and were contained in the application's src/main/jniLibs/<abi>/ directory. Now, the only way I can get it to extract while supplying them as a remote dependency via an aar is by including in the Manifest android:extractNativeLibs="true".

How can I get things to extract properly w/o needing to declare that in my Manifest?

Is there something I need to declare in the remote library's Manifest so upon merge, Android knows about the shared native lib and it will extract properly? Do I need an Android.mk file?

Guidance/help would be very much appreciated!

05nelsonm
  • 311
  • 3
  • 5

2 Answers2

0

This answer has a fairly detailed description of the use of the extractNativeLibs functionality, and how you have to change your packaging/deployment process in order to leave it set to false: https://stackoverflow.com/a/44704840/13924538. tl;dr: your APK will be a larger download, but loads faster and takes up less overall space on the handset because it doesn't need to be uncompressed.

The documentation for extractNativeLibs is here, which also offers some insight: https://developer.android.com/guide/topics/manifest/application-element#extractNativeLibs

If set to false, then your native libraries must be page aligned and stored uncompressed in the APK.

Here's the documentation for the zipalign tool, which you could run manually or incorporate with a shell script in your deploy (pre-signing) process: https://developer.android.com/studio/command-line/zipalign

zipalign [-f] [-v] 4 infile.apk outfile.apk # f overwrites outfile.apk, v for verbose, 4 byte is the only allowed value that does anything for alignment

or, in gradle, prior to signing step(s):

task zipAlign {
   workingDir "<my apk output dir>"
   commandLine "zipalign -f -v 4 infile.apk outfile.apk"
}
lmgtfy
  • 1
  • 2
  • So after inspecting things further, the aar is being built with the .so files compressed. Is there a way to not compress the native libs such that when `different.package.B` imports them they are the raw, uncompressed files? – 05nelsonm Jul 17 '20 at 20:47
0

Adding to different.package.B's build.gradle android block

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

resolved my issue. The *.so files provided via the aar now extract to the application's native directory.

see: https://github.com/05nelsonm/TOPL-Android-TorBinary

05nelsonm
  • 311
  • 3
  • 5