本机活动和“无法加载本机库”

时间:2013-02-09 03:15:46

标签: android android-ndk makefile

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

  

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 个答案:

答案 0 :(得分:2)

查找有关加载失败的更多信息的一种有用方法是创建一个基本的Android应用程序,并使用System.loadLibraryonCreate方法中加载本机库,完全绕过NativeActivity。

e.g。

@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”未找到引起

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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

我已经看到,当图书馆普遍存在,然后在名称中添加-1,-2等时,它会执行此操作。不确定为什么,但很确定它是一个版本控制的东西,你可以通过卸载或全新安装来解决。

答案 3 :(得分:1)

这是由于缺少依赖性(甚至实现)而发生的。您可能无法加载库:libFoo.so&#34;但真正的依赖缺失可能是libBar.so,它依赖于libFoo.so。或者你可能只是声明了函数并调用它们但没有实现它们。

问题是由于构建so文件的方式有效。使用gcc构建共享对象时,链接步骤并非真正发生。例如,在libFoo.so中,您可以声明一个myFunc()原型并调用它。您可以跳过myFunc(){}的实现。 gcc很乐意为你建立一个.so文件。它会愉快地结束在apk中。但是,当它加载库时,这将打破&#34;无法加载库&#34;消息。

有两种方法可以解决这个问题:你要么做AndrewJC在答案中告诉你的事情。或者您开始​​注释代码,直到您能够再次加载。因此找不到函数实现。

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