没有找到JNI_OnLoad,跳过初始化 > 应用程序关闭。

16

各位朋友,

我正在开发一款安卓应用程序,需要使用一个第三方.so库。按照该库的说明,我使用ndk-build构建了它,并希望将其包含到我的安卓项目中。

因此,我按照文档PREBUILTS.html中描述的步骤,在jni/prebuilt目录成功构建了新的.so文件。现在,我尝试在一个简单的测试安卓应用程序中使用这个.so文件提供的功能。具体做法如下:

static {
  Log.i("load so > ","load so");
  System.loadLibrary("xyz");
   }
/* The native functions */
private static native int openFile(String filename);

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    try{
        String path =  getPathForDownloadDirectoryFile();
        Log.i("file path> ", path);
        int num= openFile(path);
    }catch(Exception e){
        Log.e(">", "could not open the file");
    }
}
现在当我运行我的应用程序时,我收到一个调试消息,内容为: No JNI_OnLoad found in /data/data/com.example.myfirstapp/lib/xyz.so 0x411e6738, skipping init 然后应用程序关闭。
更多信息,请查看以下错误日志:
No JNI_OnLoad found in /data/data/com.example.mysecondapp/lib/xyz.so 0x411e67a0,   skipping init
W/dalvikvm(  570): No implementation found for native    Lcom/example/mysecondapp/MainActivity;.openFile:(Ljava/lang/String;)I
D/AndroidRuntime(  570): Shutting down VM
W/dalvikvm(  570): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
E/AndroidRuntime(  570): FATAL EXCEPTION: main
E/AndroidRuntime(  570): java.lang.UnsatisfiedLinkError: Native method not found:  com.example.mysecondapp.MainActivity.openFile:(Ljava/lang/String;)I
E/AndroidRuntime(  570):    at com.example.mysecondapp.MainActivity.openFile(Native  Method)
E/AndroidRuntime(  570):    at   com.example.mysecondapp.MainActivity.onCreate(MainActivity.java:31)
E/AndroidRuntime(  570):    at android.app.Activity.performCreate(Activity.java:5008)
E/AndroidRuntime(  570):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
E/AndroidRuntime(  570):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
E/AndroidRuntime(  570):    at    android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
E/AndroidRuntime(  570):    at android.app.ActivityThread.access$600(ActivityThread.java:130)
E/AndroidRuntime(  570):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
E/AndroidRuntime(  570):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(  570):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(  570):    at android.app.ActivityThread.main(ActivityThread.java:4745)
E/AndroidRuntime(  570):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(  570):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(  570):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
E/AndroidRuntime(  570):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
E/AndroidRuntime(  570):    at dalvik.system.NativeStart.main(Native Method)
W/ActivityManager(  146):   Force finishing activity com.example.mysecondapp/.MainActivity

据我所见,openFile()方法的本地实现未找到,但是相同的xyz.so库与第三方的原始示例应用程序非常完美地配合使用。 我对Android-ndk世界还很陌生。

Java-Android-NDK高手们...你们能猜到我可能漏掉了什么吗?在这里,我将非常感激任何帮助 :)

4个回答

17

正如guycole所说,“No JNI_OnLoad”仅是一个警告,你的问题在其他地方。

正如你所提到的,你成功编译了你的“so”文件,问题可能出现在你的C / C ++代码中的函数签名上,应该像这样:

JNIEXPORT jint JNICALL Java_com_your_package_class_method(JNIEnv *d, jobject e, jstring f)
{
//some action

}

函数签名来自使用 javah 工具生成的头文件。您需要生成头文件并将函数签名与您的包名称一起使用。对于不同的包和类名称,头文件和相应的函数签名将会改变。

worked pretty neat with the original sample app from the third party

这可能是它在示例应用程序上运行而不是您的应用程序上运行的原因。

参考:https://thenewcircle.com/s/post/49/using_ndk_to_call_c_code_from_android_apps


没错!包名可能是原因!让我用正确的打包方式试一下。然后再回复你,谢谢! - Bhuvnesh Pratap
我使用自己的新软件包结构构建了.so文件,但是当我尝试将apk安装到设备上时,即使xyz.so位于Project_folder/libs/arm_folder下,我仍然收到“Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY]”错误。您有什么想法是什么原因? - Bhuvnesh Pratap
请粘贴您的Makefile并尝试运行链接中给出的示例,这样您就可以获得一些清晰度。 - Sunny Kumar Aditya
1
它应该在 Project_folder/libs/armrabi 中。你也可以使用WinRAR或其他解压工具打开 .apk 文件,查看它包含哪些 .so 文件。 - Alex Cohn
1
我弄错了我的AndroidManifest文件,因此出现了错误!现在一切都运行正常。谢谢大家 :) - Bhuvnesh Pratap

6
"没有JNI_OnLoad"的提示只是一个警告。JNI_OnLoad是一个可选的初始化挂钩。
我猜你的问题在于openFile()方法内部。尝试注释掉从Java调用的语句,看看进展如何。
我在http://guycole.blogspot.com/2012/03/yet-another-android-ndk-blog-posting.html上写了一篇关于JNI和一些示例代码的博客文章,也许你会觉得有用。
祝你好运。"

谢谢 guycole!你的文章确实非常全面。 - Bhuvnesh Pratap
没错。你的博客文章也写得很好。提供 JNI 回调到 Java 的源代码是个不错的点睛之笔。 - Brent Faust

2

这个还附带有日志

??-?? ??:??:??.???: INFO/(): java.lang.UnsatisfiedLinkError: Couldn't load *: findLibrary returned null

对吗?

我认为这是android.mk文件的问题。 1:尝试切换到armabi v7。 2:load函数将调用open()。检查so的权限。


0

正如之前的回答所提到的,No JNI_OnLoad 只是一个警告。

我曾经遇到过类似的问题,后来发现是由于文件操作引起的。

我的应用程序没有外部存储写入权限。在清单中添加以下代码后,它就可以正常工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接