【问题标题】:Android NDK UnsatisfiedLinkError - a surprising reasonAndroid NDK UnsatisfiedLinkError - 一个令人惊讶的原因
【发布时间】:2013-07-22 23:41:44
【问题描述】:

2013 年 8 月 7 日更新: 现在问题已经解决了,但是错误的原因出乎意料,所有通常的此类错误嫌疑人在开始时都被消除了,我学到了一些新东西。请参阅下面的答案。


我在这里很绝望。有一个带有本机库的 Android 应用程序,我从中调用一个方法。在我测试的所有系统上都没有问题,并且该程序已在 Google Play 中发布,没有任何故障报告,被成千上万的用户使用。现在,HTC One 手机的新 ROM(Android 版本 4.2.2)显然已经出局。用户声称它是官方版本,从官方渠道升级。当他们尝试启动我的应用程序时,它崩溃了,并且堆栈跟踪显示:

java.lang.UnsatisfiedLinkError: 未找到本机方法...

我知道的方法名称就在那里,并且刚才在同一台设备上安装了 Android 4.1 时运行良好。我在模拟器中的Android 4.2.2下测试(没有这个特定的设备),没有问题。此外,用户尝试卸载并重新安装应用程序,结果相同。即使向他们发送私人构建,没有任何 ProGuard/Dexguard 保护也无济于事。

还有什么会导致 Android 上的 java.lang.UnsatisfiedLinkError?或者我应该假设这个 HTC ROM 只是有问题???有没有其他人在使用 Android 4.2.2 的 HTC One 上遇到过类似的问题?

2013 年 7 月 24 日编辑

在下面的 cmets 中,另一位开发人员建议系统可能无法找到我的本机库。我通过从设置中完全删除本机库文件在 Genymotion 4.2.2 模拟器上进行了试验。这种情况下报错信息不同,得到:

W/System.err:原因:java.lang.UnsatisfiedLinkError:无法从加载器 dalvik.system.PathClassLoader[dexPath=/data/app/com.hyperionics.avar-2.apk,libra 加载 cld ryPath=/data/app-lib/com.hyperionics.avar-2]:findLibrary 返回 null

在我从使用 Android 4.2.2 的 HTC One 用户那里收到的堆栈跟踪消息中,我看到了以下错误消息:

原因:java.lang.UnsatisfiedLinkError:未找到本机方法:com.hyperionics.avar.CldWrapper.detectLangNative:(Ljava/lang/String;)[Ljava/lang‌​/String;

对我来说,系统似乎根据需要找到了 libcld.so 文件,但没有找到它需要的方法。为什么???我知道该方法在那里,根据需要导出,并且所有其他设备和系统,也包括这些运行 Android 4.2.2 的设备和系统,都可以找到它。只有带有 4.2.2 的 HTC One 出现故障...

2013 年 7 月 25 日更新

开始赏金 50 代表。点,因为我没有 HTC One 并且卡住了。将接受指出解决问题的方法的答案 - 回答者将测试我的代码模块。证明它有效 - 或证明这确实是最近用于 HTC One 的 Android 4.2.2 ROM 中的一个错误。有问题的应用是https://play.google.com/store/apps/details?id=com.hyperionics.avar

2013 年 7 月 31 日更新

赏金的最后一天,仍然没有答案,没有建议......到目前为止,我收到的所有此类错误报告都来自欧洲,报告的品牌是“htc_europe”或“vodafone_fr”。也许错误仅限于欧洲(法国 + 德国)......如果有人将 HTC One 和 Android 更新到 4.2.2,如果错误发生在其他国家或其他提供商,我会很感兴趣。

格雷格

【问题讨论】:

  • 这个库是为 armeabi-v7 编译的吗?您是否有任何其他严格在 armeabi 上运行的库。当您有 2 个使用 armeabi 和 armeabi-v7 编译的库时,系统很难决定加载哪个库。尝试将库移动到与 armeabi 版本相关的合适文件夹中。
  • @NikolaDespotoski - 感谢您的回答!在 APK、libs 文件夹中,我有子文件夹“armeabi”、“armeabi-v7a”和“x86”。每个都包含带有相关功能的 libcld.so。在我的新开发中,ARM 代码是在“拇指”模式下编译的已发布代码。构建我切换到“arm”模式。不知道还能想到什么。有问题的应用程序是play.google.com/store/apps/details?id=com.hyperionics.avar
  • 你是对的,使用 System.loadLibrary() 应该简单直接。我很确定 HTC ROM 在从哪个文件夹获取 libcld 时会感到困惑。我的直觉说,从 armeabi 获取 lib 或从 armeabi-v7a 获取 lib 是两难的。尝试使用运行 API 级别 17 的 Genymotion 模拟器,它确实显示了所有 Dalvik 日志输出,您可以注意到系统在库上的外观以及它如何决定加载哪个库。 " 还可以在找到架构后尝试使用 System.load("/system/lib/armabi/libcld.so"); 加载具有完整路径的库。
  • @NikolaDespotoski 感谢您提到 Genymotion 并提示我查找它。以前从未听说过。
  • 谢谢。是的,我通过他们的支持网站写信给 HTC。对我来说,这看起来像是他们系统更新中的一个错误,但试着向用户解释一下……我想时间会证明一切的。感谢您的支持,祝您一切顺利。

标签: android android-ndk unsatisfiedlinkerror


【解决方案1】:

在赏金期间没有令人满意的答案。我订购了该设备,并且必须调试设备 ROM 中最有可能是系统错误以进行 Android 4.2.2 更新...

2014 年 6 月 20 日更新 偶尔出现 UnsatisfiedLinkError 的另一个原因

事实证明,有时在从 Google Play 更新应用时,未正确安装原生库。可能安装程序空间不足,或者出现了其他一些奇怪的系统错误。另请参阅this SO question 和答案。

2013 年 8 月 6 日更新 - 谜团解开!

我从 Google Play 订购的 HTC One 到货了,而且……谜团解开了!同样的崩溃也发生在 Google Play 的原始 Android 4.2.2 上。问题是我的库名称:cld,它生成了一个名为 libcld.so 的共享库。显然系统有另一个同名的共享库,当然我期望的方法不存在......可能是一些“插件”将另一个 libcld.so 加载到进程内存中,而我自己的库被跳过了。我重命名了原生库,程序立即开始运行。

我不知道在不同版本的 Android 上可能会出现这种名称冲突...阅读此内容的人是否在 NDK 文档中的某处看到了关于它的警告?我想从现在开始,我会在我创建的所有本地库上加上我的公司名称或其他名称。

【讨论】:

  • 以前,赏金不会消失——要么是赢家得到了全部,要么是在最佳答案和 OP 之间分配(我认为)......
  • 嗯。这次我的50分。刚刚消失了,@Flotolk 给出的唯一其他答案也没有因此获得任何积分。不过,我猜我现在恢复了,因为我在问答中获得了赞成票。
  • 嗯,一年前我很惊讶我没有在同样的情况下至少部分恢复它(标记没有给出任何东西,我也没有费心搜索/询问关于元的问题)。还是这最终开始腐烂? :)
  • 我猜你是不幸在暑假期间遇到了麻烦。我相信这就是为什么我在七月错过了你的问题。赏金经常发挥作用。
【解决方案2】:

您可以尝试从您的库中获取方法定义,并将其重写到您的一个类中,为该方法指定一个不同的名称。这可能很繁琐,但至少你可以确定你的程序能够找到方法……

【讨论】:

  • 感谢您的帮助!实际上,我得到了堆栈跟踪,其中两个不同的方法名称被列为丢失。但是你的意思是我应该用 Java 重写 C++ 方法以使其在故障设备上工作吗?好吧,我用 Java 编写了它们,编写本机库的全部目的是让应用程序更快。它适用于除 HTC One 以外的所有设备,甚至适用于旧版 Android 的 HTC One...
【解决方案3】:
defaultConfig {
    ...
    ndk {
        abiFilters "armeabi-v7a", "x86", "armeabi", "mips"
    }
}

【讨论】:

    猜你喜欢
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    • 2011-04-29
    • 1970-01-01
    • 2022-06-11
    • 2015-06-05
    相关资源
    最近更新 更多