dlopen 在旧 Android 版本上失败

dlopen fails on older Android versions

我在运行时像这样加载我的原生库

dlopen("mylib.so", RTLD_LAZY);

这在最新版本的 android 上运行良好(例如棉花糖、牛轧糖等)。但是,在旧版本(例如 Jellybean)上,这会失败并在 logcat

中显示以下消息
Failed to load mylib.so. Error: Cannot load library: 
load_library[1093]: Library 'mylib.so' not found

我已确保 mylib.so 是 apk 的一部分。我将其作为 x86armeabi_v7a 架构的一部分。

myapp.apk
- lib
  - armeabi-v7a
       mylib.so
  - x86
       mylib.so

根据 readelf -d mylib.so | grep NEEDED 依赖项是

 0x00000001 (NEEDED)                     Shared library: [liblog.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]

我尝试在加载 mylib.so 之前通过 dlopen 加载这些依赖项。虽然加载这些依赖项成功,但加载 mylib.so 总是失败并出现相同的错误。

如前所述,我只在 android 的旧版本上看到此故障。

我怎样才能让它工作?在此先感谢您的帮助。

尝试将文件夹名称从 lib 更改为 jniLibs

Lollipop 之前,您必须提供 dlopen() 的完整路径。这个路径可以在Java中用getApplicationInfo().nativeLibraryDir.

得到

无论如何,你可以检查/data/data/your.package/lib目录的内容(有时它有-1后缀,或者以 /data/app-lib 开头)。这个目录是世界可读的,所以你应该从 Android Studio 或 adb shell.

那里看到文件 libmylib.so

观察到的行为的另一个原因可能是旧设备不支持 armeabi-v7a ABI。使用 adb shell getprop.

很容易检查

此外,请确保使用正确的 APP_PLATFORM 构建库,这应该 match the minSdkVersion.

幸运的是,您的库没有 'private' 依赖项。但对于那些这样做的人,你也需要考虑到这一点。在 Lollipop 之前,不会自动加载这些依赖项(因为 nativeLibraryDir 没有扫描 dlopen)。您必须以反向依赖顺序加载所有库。