图4
到此,恭喜你,编译环境以及成功搭建完毕!
那么搭建完了,继续了解开发流程,然后开发个Demo试验一把。 四、 JNI开发流程
Java通过JNI机制和C/C++沟通的具体步骤 1)编写包含native本地方法的java类 2)通过javah工具生成C/C++语言的头文件 3)使用C/C++语言实现头文件
4)使用交叉编译工具对C/C++本地代码进行编译,最后通过链接生成*.so可执行的C/C++库
5)实际执行Java代码去和本地的C/C++代码互相沟通
五、实例演练
1.在TestNdk工程中新建一个JniClient.class(为了调用C/C++代码),其内容如下:
package com.ndk.test;
public class JniClient {
static public native String AddStr(String strA, String strB); static public native int AddInt(int a, int b); }
2.生成 .h 的c++头文件
(1)用cmd命令定位到JniClient.class 所在目录,输入“javac JniClient.java“后回车,生成JniClinet.class文件(如果是用的Eclipse建的工程,在TestNdk\\bin\\classes\\com\\ndk\\test目录下就已经有JniClinet.class文件了)。
(2)将JniClinet.class拷贝到TestNdk\\bin\\classes\\com\\ndk\\test目录,将cmd命令定位到TestNdk\\bin\\classes目录,输入”javah com.ndk.test.JniClient“后回车,在TestNdk\\bin\\classes目录下就生成了C++头文件com_ndk_test_JniClient.h com_ndk_test_JniClient.h的文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include
/* Header for class com_ndk_test_JniClient */
#ifndef _Included_com_ndk_test_JniClient #define _Included_com_ndk_test_JniClient #ifdef __cplusplus extern \ { #endif /*
* Class: com_ndk_test_JniClient * Method: AddStr
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; */
JNIEXPORT jstring JNICALL Java_com_ndk_test_JniClient_AddStr (JNIEnv *, jclass, jstring, jstring); /*
* Class: com_ndk_test_JniClient * Method: AddInt * Signature: (II)I */
JNIEXPORT jint JNICALL Java_com_ndk_test_JniClient_AddInt (JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus }
#endif
#endif
3.在jni目录下新建一个Android.mk文件,其内容如下(关于mk文件需要注意,很重要,还有c和c++文件的mk文件还不一样,此处是调用c语言的mk文件,至于其他的怎么调用,这个自己去百度吧,在此就不多说了)
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)
LOCAL_MODULE := TestNdk
LOCAL_SRC_FILES := com_ndk_test_JniClient.c include $(BUILD_SHARED_LIBRARY)
4. 将刚刚手动生成的com_ndk_test_JniClient.h拷贝到TestNdk工程的jni目录下,
然后新建一个com_ndk_test_JniClient.c文件完成头文件中函数的实现,其内容如下(本来想写两个方法的,现在只讲解第一个方法,返回一个字符串“HelloWorld from JNI ”,另一个方法是一个a+b的运算,方法写到这里,感兴趣的可以自己去研究): com_ndk_test_JniClient.c
#include \ #include
#ifdef __cplusplus extern \ { #endif /*
* Class: com_ndk_test_JniClient * Method: AddStr
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; */
JNIEXPORT jstring JNICALL Java_com_ndk_test_JniClient_AddStr (JNIEnv *env, jclass arg, jstring instringA, jstring instringB) {
jstring str = (*env)->NewStringUTF(env, \);
return str; } /*
* Class: com_ndk_test_JniClient * Method: AddInt * Signature: (II)I */
JNIEXPORT jint JNICALL Java_com_ndk_test_JniClient_AddInt (JNIEnv *env, jclass arg, jint a, jint b) {
return a + b; }
#ifdef __cplusplus } #endif
此刻,当编辑com_ndk_test_JniClient.c并保存后,project下的—clean 一下工程,就可以看到TestNkd工程下的obj/local/armeabi目录下将自动生成libTestNdk.so库。
5.在TestNdkActivity.java中完成对JniClient.java中函数的调用(首先静态加载动态链接so库):
package com.ndk.test;
import android.app.Activity; import android.os.Bundle;
import android.widget.TextView;
public class TestNdkActivity extends Activity { static {
System.loadLibrary(\ }
/** Called when the activity is first created. */ @Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.main);
//第一个方法传入的两个参数没有做操作,直接返回hello jni,不用管
相关推荐: