今晚測試了一個簡單的JNI實例,雖說簡單,並且有大牛的blog(http://blog.csdn.net/javatiger427/article/details/6115693)參照,但最後竟然也耗費了一晚上的時間。。。
首先建立一個Android的工程,JNITest,Acitivity的代碼如下:
public class JNITestActivity extends Activity {
/** Called when the activity is first created. */
public native String stringFromJNI();
static {
System.loadLibrary("JNITest");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText(stringFromJNI());
setContentView(tv);
}
}
stringFromJNI()函數是聲明一個C來實現的函數;static中的代碼去加載.so文件,其需要注意兩個方面:一是loadLibrary函數,而不是load函數;二是”JNITest”是固定這樣寫的,它與Android.mk中的文件的Module的命名相對應,而不是什麼文件索引什麼的。然後是生成一個頭文件:
可以通過獲取以.h文件來獲取函數申明。打開命令行,鍵入cd (這個路徑是使用Eclipse建立的工程目錄的src的路徑),目的是設置工程目錄。然後鍵入:javah -jni com.cn.lhq.JniTest,結果如果失敗,那就是因爲沒有把MyFirst.class文件拷貝到F:/workspace/MyFirstJNI/src/com/cn/lhq之下,原因是Eclipse的文件管理機制會將.class文件和.java文件分開到不同的目錄,解決方法是將F:/workspace/MyFirstJNI/bin/com/cn/lhq的所有.class文件都拷貝到他的目錄下面。再次運行javah -jni com.cn.lhq.JniTest即可。然後就可以看到在F:/workspace/MyFirstJNI/src下多出了一個文件:com_cn_lhq_JniTest.h,通過這個文件,我們就知道了本地接口的函數名,於是我們就根據函數名寫一個com_cn_lhq_JniTest.c文件, 代碼如下:
#include<string.h>
#include"zjut_guoxu_JNITestActivity.h"
JNIEXPORT jstring JNICALL Java_zjut_guoxu_JNITestActivity_stringFromJNI(JNIEnv * env, jobject mObj){
return (*env)->NewStringUTF(env,"Hello from JNI !");
}
最後編譯:
建立jni文件夾,將C文件放入,copy一個Android.mk文件,內容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JNITest
LOCAL_SRC_FILES := zjut_guoxu_JNITestActivity.c
include $(BUILD_SHARED_LIBRARY)
然後就是用ndk-build編譯了,最後運行!