2011-06-14 47 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"); 
}