继上一篇,我们在native接口中编写了2个方法
生成的相应.h文件
这时,需要我们自己去完善.c文件
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>#include <android/log.h>#include <stdio.h>#include <string.h>#include <stdlib.h> /* Header for class led_oki_com_jnidemo_AppJNI */ #ifndef _Included_led_oki_com_jnidemo_AppJNI#define _Included_led_oki_com_jnidemo_AppJNI#ifdef __cplusplusextern "C" {#endif 这段可不变,固定
#include "android/log.h" #define TAG "jnidemo-jni-test" // 这个是自定义的LOG的标识 #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) // 定义LOGD类型 这段主要是自定义的LOG标识,相当于Android中的LOG.D()方法 方法一:getStringFromNative
JNIEXPORT jstring JNICALL Java_com_oki_led_jni_AppJNI_getStringFromNative(JNIEnv * env, jobject jObj){ LOGD("log string from ndk."); return env->NewStringUTF(env,"Hello From JNI!");} 这段,对应我们的native写的方法之一getStringFromNative,自定义的LOG使用则是使用自定义的方法名LOGD("提示内容")这个方法意思是返回一个String类型的数据,数据是Hello From JNI!在Android里就可以接收到这段StringAppJNI appJNI = new AppJNI();String msg = appJNI.getStringFromNative();这时,msg接收的数据就是Hello From JNI! 方法二:doCoordTest(COORD coord)
JNIEXPORT jobject JNICALL Java_com_oki_led_jni_AppJNI_doCoordTest(JNIEnv *env, jobject obj, jobject coord) { jclass coordClass = (*env)->GetObjectClass(env, coord); if( coordClass){ jboolean iscopy; jfieldID xId = (*env)->GetFieldID(env, coordClass, "x", "I"); jint x = (int)(*env)->GetIntField(env, coord, xId); LOGD("x = %d", x); jfieldID yId = (*env)->GetFieldID(env, coordClass, "y", "I"); jint y = (int)(*env)->GetIntField(env, coord, yId); LOGD("y = %d", y); jfieldID widthId = (*env)->GetFieldID(env, coordClass, "width", "I"); jint width = (int)(*env)->GetIntField(env, coord, widthId); LOGD("width = %d", width); jfieldID heightId = (*env)->GetFieldID(env, coordClass, "height", "I"); jint height = (int)(*env)->GetIntField(env, coord, heightId); LOGD("height = %d", height); } jclass cls = (*env)->FindClass(env, "com/oki/led/jni/nativeobj/COORD"); jmethodID id = (*env)->GetMethodID(env, cls, "<init>", "()V"); jobject paramOut = (*env)->NewObjectA(env, cls, id, 0); return paramOut; } 其中,COORD是在Android中创建的一个COORD对象类
public class COORD { public int x; public int y; public int width; public int height; /** * 设置初始值 * 为什么要设置初始值:防止在执行c文件中,数据出错或内容溢出等不必要的问题,也减少在c文件中对数据的判断,懒人方法(可用可不用) */ public COORD() { x = 0; y = 0; width = 0; height = 0; }}
如果native中设置的传递一个类,那么c文件中,一开始接收的数据应该是jobject类型,通过jobject类型转换成jclass类型,再取出class类中各个数值 jclass coordClass = (*env)->GetObjectClass(env, coord); 片段1:取值 //取类中的数值 x IDjfieldID xId = (*env)->GetFieldID(env, coordClass, "x", "I"); //将 x ID 转换成相应类型的 x 数值jint x = (int)(*env)->GetIntField(env, coord, xId); //打印 x 数据,用于在Android运行过程中,判断该数值是否正确LOGD("x = %d", x); 片段2:调用初始方法 //查找class 类 COORDjclass cls = (*env)->FindClass(env, "com/oki/led/jni/nativeobj/COORD"); //对该类调用其初始化方法jmethodID id = (*env)->GetMethodID(env, cls, "<init>", "()V"); //将cls类中的数据再转成jobject类 jobject paramOut = (*env)->NewObjectA(env, cls, id, 0);//将数据返回出去return paramOut; 片段3:赋值 如果需要将片段1中的取值内容返回出去,需要再新创建一个jobject方法承载这些数据//查找class 类 COORDjclass cls = (*env)->FindClass(env, "com/oki/led/jni/nativeobj/COORD"); //可要可不要jmethodID id = (*env)->GetMethodID(env, cls, "<init>", "()V"); //将cls类中的数据再转成jobject类 jobject paramOut = (*env)->NewObjectA(env, cls, id, 0); jfieldID xId = (*env)->GetFieldID(env, coordClass, "x", "I");//将xId赋值为3(*env)->SetIntField(env, paramOut, xId, 3); return paramOut; 基本上就是这样,遗留问题:赋值是否有更方便的方法?里面是否有一些代码重复?
时间: 2024-12-10 09:21:04