7

我有一个本机应用程序,它总是在带有DalivikART运行时的 Android KitKat 上运行,但它现在在Android L上崩溃并出现以下跟踪:

E/art(12810): dlopen("/data/app-lib/com.mylib.example", RTLD_LAZY) failed: dlopen failed: cannot locate symbol "issetugid" referenced by "mylib.so"...
D/AndroidRuntime(12810): Shutting down VM
E/AndroidRuntime(12810): FATAL EXCEPTION: main
E/AndroidRuntime(12810): Process: com.mylib.example, PID: 12810
E/AndroidRuntime(12810): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "issetugid" referenced by "mylib.so"...
E/AndroidRuntime(12810):    at java.lang.Runtime.loadLibrary(Runtime.java:364)
E/AndroidRuntime(12810):    at java.lang.System.loadLibrary(System.java:610)

Android L 中的 ART 运行时与 KitKat 不同吗?目前还没有新的 NDK 可用,因此,如何避免此崩溃,因为似乎issetugid不再支持该功能。

4

2 回答 2

1

该问题已在最终的 Android 5.0 版本中得到修复。无需重新编译现有的二进制文件。

但是,如果本机库是使用目标android-21编译的,它会在以前的 Android 版本(< 5.0)上失败

于 2014-11-13T16:50:23.913 回答
0

我想我可能有答案,如果我错了,请纠正我。我遇到过类似的问题,现在它已修复(或者我找到了解决方法)

在向 JNI 注册本机方法时,有两种方法。

1) 在您的 .cpp 文件中实现 JNI_OnLoad() 方法,并使用适当的类注册您的本地方法。检查 - http://developer.android.com/training/articles/perf-jni.html#native_libraries示例 - https://android.googlesource.com/platform/development/+/master/samples/SimpleJNI/jni/native .cpp

2)本地方法有一个特定的命名约定,必须添加类路径(包括包)。检查 - http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp615 这里我们不需要实现任何方法。JVM 从二进制文件中它自己的符号名称中发现本机方法。

第一种方法似乎在 Android ART 运行时不起作用(ART 在 kitkat 中是可选的,它将是 Lolipop 中唯一的运行时)。我不确定它为什么不起作用。但我认为原因是因为 ART 的执行方式。(字节码在安装时本身而不是运行时被转换和缓存,因此应用程序运行得更快)。因此,由于未加载本机库(未调用 on_load),因此转换为机器代码有时会失败

使用第二种方法注册本地人。它应该工作。唯一的缺点是现在你的函数名会很长而且看起来很糟糕(我敢打赌,没有一个函数会适合 100char 限制)。再见了函数名的可读性。

希望这可以帮助

干杯,虾

于 2014-10-28T19:39:18.507 回答