android - dlopen 在旧版 Android 上失败

标签 android android-ndk dlopen

我正在运行时像这样加载我的 native 库

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 需要 依赖项是

 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 上看到此故障。

我怎样才能让它发挥作用?预先感谢您的帮助。

最佳答案

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)。您必须以反向依赖顺序加载所有库。

关于android - dlopen 在旧版 Android 上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50982902/

相关文章:

android - 如何设置 android.support.v7.widget.SearchView 的样式

android - 滚动时始终在屏幕底部显示 LinearLayout 中的按钮

android - Android NDK 的最新 C++11 功能

c++ - 运行时动态加载和单例

ios - dlopen 有没有办法在 iOS 上重新加载 dylib 文件?

c++ - 如何从当前可执行文件中获取函数地址?

java - BottomAppBar 抛出 IllegalArgumentException

android - 通过 NDK 访问 Android 传感器

android - 调用 System.loadLibrary 时未调用 onJNILoad

带有 Switch onCheckedListener 的 Android ListView 很奇怪