android NDK 四、 Java call Native And Native call Java
1、在java中调用 Native代码,JNI的写法
#include <string.h> #include <jni.h> #include <stdio.h> #include <android/log.h> #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__)) JNIEXPORT jstring JNICALL Java_com_ndk_NDKFirstActivity_getTime( JNIEnv* env,jobject thiz ) { LOGI("hello lipeil ,you are great ! hh"); return (*env)->NewStringUTF(env, "the time is 2012 5 17"); } JNIEXPORT jstring JNICALL Java_com_ndk_NDKFirstActivity_getLine(JNIEnv* env , jobject thiz , jstring jstr) { char buf[128]; const jbyte *str; str = (*env)->GetStringUTFChars(env ,jstr, NULL); if(str == NULL) { return NULL; } LOGI(str); (*env)->ReleaseStringUTFChars(env,jstr,str); return (*env)->NewStringUTF(env,"yo ni yao diao"); } /**整型数组的转换*/ JNIEXPORT jint JNICALL Java_com_ndk_NDKFirstActivity_sumArrayRegion(JNIEnv* env , jobject thiz , jintArray arr) { jint buf[10]; jint i, sum=0; (*env)->GetIntArrayRegion(env , arr ,0,10,buf); for(i=0 ; i<10 ;i++) { sum += buf[i]; } return sum; } JNIEXPORT jint JNICALL Java_com_ndk_NDKFirstActivity_sumArray(JNIEnv* env , jobject thiz , jintArray arr) { jint i=0, sum=0;// 需要先初始化 jint* buf ; buf= (*env)->GetIntArrayElements(env , arr ,NULL); if(buf == NULL) { return 0; } /** or we can use GetArrayLength get the buf length; */ while(*(buf+i) !='\0') { sum += buf[i]; i++; } (*env)->ReleaseIntArrayElements(env ,arr ,buf ,0); return sum; }
2、 在Native 中回调 Java代码,写法
#include <string.h> #include <jni.h> #include <stdio.h> #include <android/log.h> #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__)) #define LOGII(...) ((void)__android_log_print(ANDROID_LOG_INFO, "the int value is : %d", __VA_ARGS__)) JNIEXPORT void JNICALL Java_com_ndk_NDKFirstActivity_acessField(JNIEnv * env , jobject obj) { jfieldID fid; jstring jstr; const char* str; /**从对象中回去类*/ jclass cls = (*env)->GetObjectClass(env ,obj); /**根据类、字段、和字段类型获取字段id*/ fid = (*env)->GetFieldID(env ,cls,"str" ,"Ljava/lang/String;");//类型后面的分号不能省略 if(fid == NULL) { return; } /**根据字段ID 和对象 获取值*/ jstr = (*env)->GetObjectField(env ,obj,fid); str = (*env)->GetStringUTFChars(env ,jstr ,NULL); if(str == NULL) { return; } LOGI(str); (*env)->ReleaseStringUTFChars(env ,jstr,str); jstr = (*env)->NewStringUTF(env ,"I reset the str value in native c,and success"); if(jstr == NULL) { return; } /**根据对象、字段id 设置值*/ (*env)->SetObjectField(env ,obj , fid , jstr); } JNIEXPORT void JNICALL Java_com_ndk_NDKFirstActivity_accessStaticField(JNIEnv *env ,jobject obj) { jfieldID fid ; jint si; jclass cls = (*env)->GetObjectClass(env , obj); fid = (*env)->GetStaticFieldID(env ,cls ,"value","I"); if(fid==NULL) { return; }
//根据类,设置静态字段值 si = (*env)->GetStaticIntField(env ,cls ,fid); //LOGI(si+""); (*env)->SetStaticIntField(env ,cls ,fid ,2012); } JNIEXPORT void JNICALL Java_com_ndk_NDKFirstActivity_invokeMethod(JNIEnv *env ,jobject obj) { jclass cls = (*env)->GetObjectClass(env ,obj); jmethodID mid = (*env)->GetMethodID(env ,cls ,"callback","()V"); if(mid == NULL) { return; } //更加对象、方法字段,调用 Java 方法 LOGI("i invoke callback in native c"); (*env)->CallVoidMethod(env ,obj ,mid); } JNIEXPORT void JNICALL Java_com_ndk_NDKFirstActivity_invokeStaticMethod(JNIEnv *env , jobject obj) { jclass cls = (*env)->GetObjectClass(env , obj); jmethodID mid =(*env)->GetStaticMethodID(env ,cls,"staticCallback","(I)V"); if(mid == NULL) { return; } LOGI("i invoke staticCallback in native c"); jint ji = 1000;
//根据类,方法字段,调用静态方法 (*env)->CallStaticVoidMethod(env,cls,mid ,ji); } JNIEXPORT jobject JNICALL Java_com_ndk_NDKFirstActivity_getData(JNIEnv *env , jobject obj , jint ji) {
//根据类名,获取类 jclass dataClass = (*env)->FindClass(env ,"com/ndk/Data"); if(dataClass == NULL) { return; } //根据类 获取方法字段 jmethodID cid = (*env)->GetMethodID(env ,dataClass ,"<init>" ,"(I)V"); if(cid== NULL) { return; } LOGI("i init and return a construct in native c");
//根据类、 构造方法字段 初始化 类对象 return (*env)->NewObject(env ,dataClass ,cid , ji); }