Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libs file(*.so) inside split apk doesn't extracted to folder "lib" in App Bundle #39

Closed
rafirafika opened this issue Dec 28, 2018 · 14 comments

Comments

@rafirafika
Copy link

rafirafika commented Dec 28, 2018

Hello team,
I have problem when try to read libs file (.so) within app bundle.
commonly, if we install installer file (
.apk), this .apk file will be extracted in the device on folder data/app/packageName and inside it there are "lib" folder that contain libs file.
But when I installed app bundle and when bundle is extracted on the device my folder "data/app/mypackageName/lib" is empty. all my libs files (*.so) that I need still in splitApk.apk file

preview for extracted bundle file in device
bundle

preview for extracted .apk file in device
apk file

command that I used to install aps bundle is :
install-apks --apks=!BASENAME_PATH!.apks --modules=dlc_module

Question :
Could I get all libs(*.so) files such as if we use .apk file as installer? because I need this file to handle security system in my apps
If I couldn't , Could you please give me some advice?

Btw, sorry if my question is not clear enough, my english is very bad.

@plecesne
Copy link
Contributor

From Android M, the Android platform supports uncompressed native libraries in APKs, which allows the platform to read the native libraries directly from the APK without having to extract them. This is why you don't see them in the "lib/" directory if you're testing on a device on Android M or later.

Since the Android platform reads the native libraries from the APK directly, you should probably do the same if you need to verify something on them.

There is a flag in Gradle to disable this feature but that leads to bigger APKs on users devices since the native libraries are extracted out of the APK (and thus also longer installation times), so unless there is no workaround for what you're trying to achieve, I would strongly discourage disabling it.

@google google deleted a comment Dec 30, 2018
@rafirafika
Copy link
Author

rafirafika commented Dec 31, 2018

Hy @plecesne thanks for your info and suggestion.
seems I'll choose to read native libs from Apk directly. J

@trungnd90
Copy link

@plecesne "There is a flag in Gradle to disable this feature" Could you give detail about this? I want to try disable it.

@plecesne
Copy link
Contributor

plecesne commented Sep 16, 2019

You can set the property android.bundle.enableUncompressedNativeLibs=false in the gradle.properties. Would you mind sharing why this is causing you issue?

@trungnd90
Copy link

I just want to have more free space to push some data into apk

@plecesne
Copy link
Contributor

plecesne commented Sep 16, 2019

By compressing the native libraries, the APKs served to your users will be bigger! I explained this a bit better in #118

Although the App Bundle looks bigger and the APK files look bigger, the compression performed over the wire will be more efficient, leading to smaller downloads, and the size on device will be saved as well since the platform will not have to extract it at install time (which would result in two copies of the native libraries on device: one compressed in the APK, and one uncompressed in the installation directory).

Note also regarding size limits that the Play Console doesn't not validate the size based on the size of the App Bundle but based on the download size of the generated APKs, so compressing the native libraries doesn't gain you anything there either.

@rpattabi
Copy link

You can set the property android.bundle.enableUncompressedNativeLibraries=false in the gradle.properties. Would you mind sharing why this is causing you issue?

@plecesne Thanks, but the correct property is android.bundle.enableUncompressedNativeLibs

We would like you to be aware that we couldn't use uncompressed native libs feature as we need to use the path of the .so files. For example, when we use pure data, a audio manipulating engine, we shall providing the native library path to its API for it to discover the custom externals that we built for it to consider in audio processing. So native library path is critical for our purposes. If we leave native libs uncompressed in apk, the path returned by ApplicationInfo.nativeLibraryDir does not contain native libraries anymore. So puredata engine wouldn't discover our custom externals.

Hope that makes sense. I wonder if there is a way to get valid native libraries path even if we keep native libs uncompressed in the apk.

@plecesne
Copy link
Contributor

Ah, sorry about the name, I'll edit my comment in case somebody finds it later.

Loading the library using System.loadLibrary (in java) or in dlopen (in C++) should just work on Android, the platform will find the library even if it's uncompressed in the APK. So I guess it depends how this SDK loads the library you're giving it.

@rpattabi
Copy link

Good to know that dlopen would work fine. Still there are libraries that need a lookup "path" to discover and load plugins/extensions in the form of .so files (like puredata mentioned above). This is typically the case with audio libraries. We used to supply them with the path provided by ApplicationInfo.nativeLibraryDir. As mentioned, this path is reported empty when native libs are uncompressed in the apk. Thus it doesn't work. So we could take advantage of this feature only if the platform provides a filesystem path that present native libs even though they still reside in apk.

Until then, android.bundle.enableUncompressedNativeLibs=false is critical for our purposes if we intend to use app bundle. We are glad to use app bundle as it reduced our app size by half! However, currently we get this warning (which is bit unsettling :--)

WARNING: The option setting 'android.bundle.enableUncompressedNativeLibs=false' is experimental and unsupported.

@plecesne
Copy link
Contributor

Depending on non-Android SDKs may require you to leave APKs compressed indeed.

Note that the warning you see was removed in 3.6 canary 3.

@riskycheng
Copy link

riskycheng commented Mar 17, 2020

you can use :
getContext().getApplicationInfo().nativeLibraryDir;
to fetch the actual native lib path if you want to use these libs like export the env with these so libs;

@omarfuzzertest
Copy link

android.bundle.enableUncompressedNativeLibs=false
It helped me a lot, I suffered a lot with this error

@vimalakshiadiga2601
Copy link

vimalakshiadiga2601 commented Oct 18, 2020

I have tried with android.bundle.enableUncompressedNativeLibs=false, unfortunately it does not create lib/arm64 folder on release builds

@0xjacklove
Copy link

android {
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
}
it works for me

shiqos added a commit to shiqos/xCrash that referenced this issue Sep 5, 2024
项目未配置 `useLegacyPackaging=true` 时,
使用AAB安装, 或最低版本为Android M以上的APK
Native库不会从APK中解压, 参考:
https://developer.android.com/guide/topics/manifest/application-element#extractNativeLibs
google/bundletool#39

此时xCrash通过 `ctx.getApplicationInfo().nativeLibraryDir` 获取的目录内容是空的
因此会出现加载xcrash_dumper失败

而通过 PathClassloader.findLibrary(libName) 获取的路径是虚拟路径, 不是真实存在的
因此直接执行也会失败

此时我们参考 Crashpad 的逻辑, 使用linker加载
参考:
https://github.com/chromium/crashpad/blob/main/client/crashpad_client_linux.cc#L114

为了避免大的改动, 默认仅在加载虚拟路径时使用linker, 实际上在所有场景都可以直接通过linker加载

支持外部自定义配置
```
.setNativeLibPath()
.setLoadNativeWithLinker()
```

如果外部没有配置,内部会自动查找
参考: AbiPathProvider.java 逻辑
shiqos added a commit to shiqos/xCrash that referenced this issue Sep 8, 2024
项目未配置 `useLegacyPackaging=true` 时,
使用AAB安装, 或最低版本为Android M以上的APK
Native库不会从APK中解压, 参考:
https://developer.android.com/guide/topics/manifest/application-element#extractNativeLibs
google/bundletool#39

此时xCrash通过 `ctx.getApplicationInfo().nativeLibraryDir` 获取的目录内容是空的
因此会出现加载xcrash_dumper失败

而通过 PathClassloader.findLibrary(libName) 获取的路径是虚拟路径, 不是真实存在的
因此直接执行也会失败

此时我们参考 Crashpad 的逻辑, 使用linker加载
参考:
https://github.com/chromium/crashpad/blob/main/client/crashpad_client_linux.cc#L114

为了避免大的改动, 默认仅在加载虚拟路径时使用linker, 实际上在所有场景都可以直接通过linker加载

支持外部自定义配置
```
.setNativeLibPath()
.setLoadNativeWithLinker()
```

如果外部没有配置,内部会自动查找
参考: AbiPathProvider.java 逻辑
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants