7

我正在尝试基于 Android NDK 文件夹中的“native-activity”示例项目构建一个 Android-10 NDK 原生活动。但是,当我打开 Eclipse 并为我的项目选择“运行方式 - > Android 应用程序”时,我的本机活动崩溃并出现以下运行时异常:

02-09 03:02:12.599: E/AndroidRuntime(881): java.lang.RuntimeException: 无法启动活动 ComponentInfo{com.example.native_activity/android.app.NativeActivity}: java.lang.IllegalArgumentException: 无法加载本机库:/data/app-lib/com.example.native_activity-1/[库名称].so

但是,我已经确认文件“lib[library name].so”已经存在于“libs/armeabi”(等)路径中。我的本机活动最终需要加载三个“.so”文件,但无论我尝试加载一个“.so”文件还是所有三个“.so”文件,此错误都会持续存在。我的“AndroidManifest.xml”文件如下:

<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.native_activity"
    android:versionCode="1"
    android:versionName="1.0">

<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />

<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="false">

    <!-- Our activity is the built-in NativeActivity framework class.
         This will take care of integrating with our NDK code. -->
    <activity android:name="android.app.NativeActivity"
            android:label="@string/app_name"
            android:configChanges="orientation|keyboardHidden">
        <!-- Tell NativeActivity the name of or .so -->
        <meta-data android:name="android.app.lib_name"
            android:value="[library name]" />
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest> 
<!-- END_INCLUDE(manifest) -->

需要做什么来修复这个运行时异常?

4

4 回答 4

2

查找有关加载失败的更多信息的一个有用方法是制作一个基本的 Android 应用程序,并使用System.loadLibrary该方法加载本机库,onCreate完全绕过 NativeActivity。

例如

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    System.loadLibrary("foo");
    System.loadLibrary("bar");
    System.loadLibrary("depends-on-foo-and-bar");
}

然后,您将不会收到 NativeActivity 提供的不太有用的“无法加载本机库”消息,而是会收到更有用的消息,例如

java.lang.UnsatisfiedLinkError:dlopen 失败:无法加载“libdepends-on-foo-and-bar.so”所需的库“lib42.so”;由找不到库“lib42.so”引起

于 2015-05-29T22:12:47.263 回答
1

在您的 JNI 文件夹中,“”设置为什么?“[库名称]”名称应设置为您正在构建的包的名称。

于 2013-03-23T11:23:58.150 回答
1

问题似乎是系统正在寻找一个名称附加了 -1 的库

(来自您的错误消息)/data/app-lib/com.example.native_activity-1

我已经看到当一个库先前存在时,andoird 会这样做,然后在名称中添加 -1、-2 等。不知道为什么,但很确定它是一个版本控制问题,您可以通过卸载或全新安装来解决。

于 2015-02-06T14:01:45.817 回答
1

发生这种情况是由于缺少依赖项(甚至是实现)。您可能会收到“无法加载库:libFoo.so”,但真正缺少的依赖项可能是 libBar.so,它由 libFoo.so 依赖。或者您可能只是声明了函数并调用了它们,但没有实现它们。

问题是由于构建 so 文件的工作方式造成的。当您使用 gcc 构建共享对象时,链接步骤并没有真正发生。例如在 libFoo.so 中,您可以声明一个 myFunc() 原型并调用它。您可以跳过 myFunc(){} 的实现。gcc 会很乐意为您构建一个 .so 文件。它会很高兴地出现在 apk 中。但是,当需要加载库时,这会因“无法加载库”消息而中断。

有两种方法可以解决这个问题:你要么按照 AndrewJC 在他的回答中告诉你的去做。或者您开始​​注释代码,直到您能够再次加载。从而定位功能实现缺失。

重要提示:添加到 so 文件的 -1 -2 后缀不是问题。该评论误导我花了几天时间才发现这些数字后缀实际上是 android 包管理器的预期行为。

于 2017-06-28T21:47:33.133 回答