8

我正在编写游戏,并且我有巨大的本地库,我正在尝试在我的主要活动中加载我的本地库,例如

 static {
        try {
            System.loadLibrary("mylib");
        } catch (UnsatisfiedLinkError e) {
            Log.d(TAG, "Unsatisfied Link error: " + e.toString());
        }
    }

我已经在内部的许多设备上测试了此代码,但没有收到此错误。但是从我发表的文章中,我确实得到了带有“ Caused by: java.lang.UnsatisfiedLinkError: Cannot load library ”的日志。注意:这种崩溃不是普遍的,只有少数人会遇到这种崩溃

  • 将库放在导出的 apk 中是否有问题?我现在已经通过eclipse自动将库放入/libs/armabi/libmylib.so?
  • 跟安卓版本有关系吗?我从 2.3(API 级别 9)开始支持 android 版本
  • 还是我需要从不同的地方加载库?
  • 还是我错过了一些非常重要的东西
  • 整个应用程序安装在 SDCARD 上是否有问题?

有关崩溃的更多信息是:load_segments: 68 failed to map segment from mylib.so

4

1 回答 1

14

考虑到您的应用程序在大多数设备上都能正常运行,并且只是有时会出现错误,因此可以安全地假设该库已正确打包在 APK 中,并且其大小/内存占用也是可以接受的。

因此,我会随心所欲地提出问题出在库的构建/编译体系结构上。大多数较新的 Android 设备使用 ARM7 处理器。您的库很可能也是针对 ARM7 架构编译的。一些较旧的设备,尤其是那些运行 Android 2.3 的设备,使用 ARM6 处理器(我有一个用于测试的此类设备 - 运行 Android 2.3.3 的 LG GT540),它与 ARM7 架构不兼容。当我尝试在我的旧 ARM6 手机上运行专为 ARM7 设计的应用程序时,我看到了与您指出的错误类似的崩溃(load_segments: 68 failed to map segment from mylib.so )。

解决这个问题的方法有以下三种:

  1. 针对两种架构编译库,并将两个单独的 .so 文件包含到 apk 中。然后在运行时确定处理器的类型并加载正确的处理器。坦率地说,我不知道这是否可能。

  2. 创建两个单独的 apk 文件——一个用于 ARM6,一个用于 ARM7——然后在清单中使用过滤器来指定相应的架构。您可以将它们都上传到同一应用程序的谷歌播放 - 清单中的过滤器将控制哪个下载到哪个设备。

  3. 仅通过在清单中指定设备要求来支持 ARM7 架构。您将失去一些客户受众,但您自己维护应用程序的两个版本的工作将减少。

编辑:根据 NDK 文档,它可以一次性为不同的架构生成多个库。您可以通过在文件中添加以下行来具体控制要定位的 CPU Application.mk

APP_ABI := arch1 arch2 arch3 ...

例如,

APP_ABI := armeabi armeabi-v7a mips

然后构建过程将创建不同版本的本地库。这些版本将需要放置在目录中的最终 apk 中

lib/<abi>/lib<name>.so

架构的名称在哪里。然后,您将加载库

System.loadLibrary("<name>");

或者,您可以为每个架构构建单独的 apk 文件,然后在 google play 上使用多 apk 功能。

您可以在 NDKCPU-ARCH-ABIS.html的子目录中的文件 file 中找到有关架构目标的所有信息。docs

于 2013-05-13T10:20:40.107 回答