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 的一部分。我将其作为 x86
和 armeabi_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)。您必须以反向依赖顺序加载所有库。
我在运行时像这样加载我的原生库
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 的一部分。我将其作为 x86
和 armeabi_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
.
观察到的行为的另一个原因可能是旧设备不支持 armeabi-v7a ABI。使用 adb shell getprop
.
此外,请确保使用正确的 APP_PLATFORM
构建库,这应该 match the minSdkVersion.
幸运的是,您的库没有 'private' 依赖项。但对于那些这样做的人,你也需要考虑到这一点。在 Lollipop 之前,不会自动加载这些依赖项(因为 nativeLibraryDir
没有扫描 dlopen)。您必须以反向依赖顺序加载所有库。