我正在尝试基于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) -->
需要做些什么来修复此运行时异常?
答案 0 :(得分:2)
查找有关加载失败的更多信息的一种有用方法是创建一个基本的Android应用程序,并使用System.loadLibrary
在onCreate
方法中加载本机库,完全绕过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包管理器的预期行为。