今晚测试了一个简单的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编译了,最后运行!