2011-06-14 48 views
6

我想在Android中运行简单的jni代码,但所有我越来越Unsatisfiedlinkerror。Android中的Unsatisfiedlinkerror(日食)

这里是我的Java代码:

package com.lipcap; 

import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 

public class MainActivity extends Activity { 
/** Called when the activity is first created. */ 

TextView a; 

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

    a=new TextView(this); 

    String b; 
    MainActivity ob=new MainActivity(); 
    b=ob.sniff(); 

    a.setText(b); 

    setContentView(a); 
} 
public native String sniff(); 

    static{ 
     System.loadLibrary("native"); 
    } 


} 

这里是我的C++代码(在$ PROJECT_PATH/JNI /):

#include<iostream> 
#include<string.h> 
#include<jni.h> 
JNIEXPORT jstring JNICALL Java_com_lipcap_MainActivity_sniff 
(JNIEnv *env, jobject obj){ 
     return env->NewStringUTF("This is Native"); 
} 

我已经使用javac遵守Java代码,并提出了头文件使用javah。

然后我运行了ndk-build。 然后我从eclipse中运行代码(安装了apk的android)。

我得到这个错误:

E/AndroidRuntime( 769): FATAL EXCEPTION: main 
E/AndroidRuntime( 769): java.lang.UnsatisfiedLinkError: sniff 
E/AndroidRuntime( 769): at com.lipcap.MainActivity.sniff(Native Method) 
E/AndroidRuntime( 769): at com.lipcap.MainActivity.onCreate(MainActivity.java:36) 
E/AndroidRuntime( 769): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
E/AndroidRuntime( 769): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
E/AndroidRuntime( 769): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
E/AndroidRuntime( 769): at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
E/AndroidRuntime( 769): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
E/AndroidRuntime( 769): at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 769): at android.os.Looper.loop(Looper.java:123) 
E/AndroidRuntime( 769): at android.app.ActivityThread.main(ActivityThread.java:4627) 
E/AndroidRuntime( 769): at java.lang.reflect.Method.invokeNative(Native Method) 
E/AndroidRuntime( 769): at java.lang.reflect.Method.invoke(Method.java:521) 
E/AndroidRuntime( 769): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
E/AndroidRuntime( 769): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
E/AndroidRuntime( 769): at dalvik.system.NativeStart.main(Native Method) 

我没有设置LD_LIBRARY_PATH。

但是,没有设置LD_LIBRARY_PATH样例代码,例如NDK提供的HelloJNI,运行非常好。

请告诉我我在哪里失踪。

+2

'MainActivity OB =新MainActivity();'为什么?您已经进入了MainActivity的实例。必须使用'this.sniff()'。 – 2011-06-14 21:33:33

+1

是的,可以使用this.sniff。 无论如何,就Unsatisfiedlinkerror而言,这不会产生任何差异。 – d34th4ck3r 2011-06-14 21:41:27

+0

从C++更改代码到C一切工作正常.. :) – d34th4ck3r 2011-06-15 20:14:01

回答

0

这是不是真的被称为完全正确......

尝试:

package com.lipcap; 

import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 

public class MainActivity extends Activity { 
    /** Called when the activity is first created. */ 

    TextView a; 

    public native String sniff(); 

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

     a=new TextView(this); 

     String b = sniff(); 

     a.setText(b); 

     setContentView(a); 
    } 

    static{ 
     System.loadLibrary("native"); 
    } 

} 

最后...这是你的Android.mk?

LOCAL_MODULE := native 
+0

Thanx,但这并没有解决问题。 – d34th4ck3r 2011-06-14 21:51:36

+0

检查编辑... Android.mk中的模块名称应与您正在加载的库名匹配。 – Maximus 2011-06-14 21:52:06

+0

此外,声明顺序在Java中并不重要。 – d34th4ck3r 2011-06-14 21:53:57

12

理查德头你所提到的:“从C++代码更改到C一切工作正常” ...

我被完全相同的问题折磨了好几天,我做确保一切由我输入(命名,Android.mk等)没有问题。每当在C,我很好。只要我改为cpp,UnsatisfiedLinkError

我终于从这个链接提示: http://markmail.org/message/fhbnprmp2m7ju6lc

这一切都因为C++名字改编的!如果在.cpp文件中没有包含extern "C"的相同函数,则名称会发生​​损坏,因此JNI找不到函数名称,因此弹出UnsatisfiedLinkError

穿上并删除你的功能extern "C" { },运行nm obj/local/armeabi/libnative.so,你会清楚地看到相同的功能没有和名称混搭。

我希望这可以帮助其他同样的问题。

0

我会给出另一个建议。我之前得到了同样的错误,但我通过“Android Native Development Kit Cookbook”解决了这个问题。

本机函数必须遵循包名,类名和方法名的特定模式。包名和类名必须与调用本机方法的Java类的包名和类名一致,而方法名称必须与该Java类中声明的方法名称相同。 这有助于Dalvik VM在运行时定位本机函数。如果遵循该规则,将在运行时导致UnsatisfiedLinkError。

例如,对于上述

你需要改变你的函数名状(不包名,如果你专注于NDK使用com.bla)

#include<iostream> 
#include<string.h> 
#include<jni.h> 

JNIEXPORT jstring JNICALL Java_lipcap_example_MainActivity_sniff 
(JNIEnv *env, jobject obj){ 
     return env->NewStringUTF("This is Native"); 
}