【问题标题】:Native application crashes on Android LAndroid L 上的原生应用程序崩溃
【发布时间】:2014-11-14 00:50:23
【问题描述】:

我有一个原生应用程序,它总是在具有 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.4.4?

标签: android android-ndk android-5.0-lollipop


【解决方案1】:

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

但是,如果原生库是使用目标 android-21 编译的,它在以前的 Android 版本 (

【讨论】:

  • arsalank2,所以你只是保持目标不变?
  • 是的,我用android-19来支持以前的版本。
  • 所以你编译了两次?或者您是说您的目标是 android-19 以支持包括 Android 5.0 在内的所有设备?您是如何定位所有设备的?
  • 不,我用目标android-19编译过一次,以支持所有设备。
  • 那么以 android-19 为目标编译适用于所有 API 级别,例如 API 9+?
【解决方案2】:

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

向JNI注册native方法时,有两种方法。

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),因此转换为机器代码有时会失败

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

希望对你有帮助

干杯, 虾肉

【讨论】:

  • 你所说的“第二种方法”是Android上JNI最初的做法;如果您真的遇到了 100 个字符的限制,您可能需要重新考虑命名空间以提高可读性。更重要的是,这些 cmets 似乎不太可能与问题中相当具体的错误有任何关系。
  • 更具体地说,这个问题的核心问题是当函数从动态链接更改为被声明为内联或宏时发生的问题,这样它的实现应该自动包含在客户端程序的构建,而不是由动态库提供。海报的现有构建假定它将由动态库在运行时提供。但是他们的新设备假定它应该包含在客户端程序中(并且不在库中提供),因此导致不兼容。
猜你喜欢
  • 1970-01-01
  • 2018-11-11
  • 1970-01-01
  • 1970-01-01
  • 2018-04-14
  • 1970-01-01
  • 2014-12-25
  • 2022-12-19
  • 1970-01-01
相关资源
最近更新 更多