不過,有時候我們仍然會需要直接呼叫底層Native的C/C++程式,
有時是因為效能,有時是因為Android提供的功能不足...
如果你也是使用Eclipse,
那麼,你必須先安裝CDT和NDK,
之後,在你想要增加JNI介面的project按右鍵,
執行"Android Tools"/"Add Native Support"後,
你會發現project下面多了一個"jni"目錄,
目錄底下還有一個"x.cpp"和"Android.mk",
到這邊,你已經完全了第一步了...
接下來,Java要如何呼JNI的函式呢?
package myTest.com;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
private native String hello(String s);
static {
System.loadLibrary("NativeMyTest");
}
}
"NativeMyTest"是你剛剛產生jni目錄時,輸入的名稱,也就是說,待會會產生NativeMyTest.so檔,
hello(String s)則是定義在JNI裡的函式,
那JNI這邊呢?
#include <jni.h>
#include <stdio.h>
#define LOG_TAG "MainActivity"
#define LOGI(...) __android_log_print(4, LOG_TAG, __VA_ARGS__);
JNIEXPORT void hello(JNIEnv* env, jobject obj, jstring str){
LOGI("hello: %s", str);
}
jint JNI_OnLoad(JavaVM* pVm, void* reserved) {
JNIEnv* env;
if ((*pVm)->GetEnv(pVm, (void **)&env, JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
JNINativeMethod nm[2];
nm[0].name = "hello";
nm[0].signature = "(Ljava/lang/String)V";
nm[0].fnPtr = (void*)hello;
jclass cls = (*env)->FindClass(env, "myTest/com/MainActivity");
(*env)->RegisterNatives(env, cls, nm, 1);
gJavaVM = pVm;
return JNI_VERSION_1_6;
}
JNI_OnLoad()是用來載入那些會被Java程式所呼叫的函式,FindClass()傳入的參數必須和Java程式的package和class名稱一樣,
執行時,看看是載入NativeMyTest.so有問題,還是沒有發現hello函式,
再來決定是那裡有問題...

沒有留言:
張貼留言