In order to try and understand how Android App Bundles deploy native .so I created a simple test app using android studio.
- The test setup:
I added some test .so's.
Also added the necessary line to the app's build.gradle file
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
- Checked building and installing a
apk
works as expected.
I see the following files/folders in the root of the apk install
base.apk
lib
oat
the lib
folder contains arm64
which contains
libexepython2.7.so
libffi.so
Note: I expected that bdiff.so would NOT be present as it doesn't following the required naming pattern of lib<name>.so
So this works as expected.
- Built Android App Bundle (AAB).
Examining the AAB
base
BUNDLE-METADATA
META_INF
BundleConfig.pb
The AAB/base
folder contains
lib
native.pb
(and others...)
I see references to lib/arm64-v8a
and lib/armeabi-v7a
in the native.pb
file.
The AAB/base/lib/
folder contains
arm64-v8a
armeabi-v7a
arm64-v8a contains
bdiff.so
libexepython2.7.so
libffi.so
So all seems reasonably sensible.
Converted to
.apks
using bundletooljava -jar bundletool.jar build-apks --bundle=release\app-release.aab --output=app.apks --overwrite
The apks archive contains a splits
folder with base-arm64_v8a*.apk
base-armeabi_v7a*.apk
files.
Confirmed that base-arm64_v8a.zip contains a lib/arm64-v8a
folder with
bdiff.so
libexepython2.7.so
libffi.so
Installed via bundletool
java -jar bundletool.jar install-apks --apks=app.apks
Looking at the install I see the following files/folders in the root of the apk install.
base.apk
lib
oat
split_config.arm64_v8a.apk
split_config.en.apk
split_config.xhdpi.apk
the lib
folder contains arm64
which is empty!
Question: Why is the lib/arm64/
folder empty? Why isn't the app bundle installing .so's?
To rule out bundletool problems, I've also tested installing AAB with google 'internal app sharing' (with a different non test app), and observed similar results.
Cause
From the gradle 3.3.0 release notes
So in summary the cause was that for Android App Bundle (AAB) native libraries are not 'installed' by default, but rather uncompressed versions are included in the apk, which I guess the app is expected to somehow use.
Use compressed and installed native libs when using older Gradles
this answer suggested setting
android.bundle.enableUncompressedNativeLibs=false
in the gradle.properties.Use compressed and installed native libs when using newer Gradles
Add the following to the android section of your apps build.gradle file
Use compressed and installed native libs when using Maui
To do the same when building Android apps with
MAUI
:Create a
BundleConfig.json
file:{
"optimizations" : {
"uncompress_native_libraries" : {}
}
}
Add
<AndroidBundleConfigurationFile>BundleConfig.json</AndroidBundleConfigurationFile>
to your MAUI.csproj
file.Verifying the AAB is using compressed native libs
To tell if you AAB uses uncompressed native libraries, and therefore doesn't extract them on install, run the following command:
If the output contains
OR the output doesn't have
uncompressNativeLibraries
set, then the AAB uses uncompressed native libraries.If you see
then it uses compressed native libraries and will uncompress them and copy them on app install.