1.类型转化
//jstr转char*
const char *chars = env->GetStringUTFChars(jstr, NULL);
//char*转jstring
jstring rtstr = env->NewStringUTF(chars);
//释放资源
env->ReleaseStringUTFChars(jstr, chars);
env->DeleteLocalRef(jstr);
//jobject转jclass
jclass clazz = (*env)->GetObjectClass(env, jobj);
jobject jobj = (*env)->AllocObject(env,jclass);
//获取String的jclass引用
jclass jstr = env->FindClass("Ljava/lang/String;");
//得到编码对象
jstring strencode = env->NewStringUTF("GB2312");
//数组长度
jsize alen = env->GetArrayLength(barr);
//对象元素
jobject obj = env->GetObjectArrayElement(bmps, i);
一维数组
//创建对象
jintArray aa = env-> NewIntArray(10);
int tmp[10];
for (int j = 0; j < 10; j++) {
tmp[j] =j;
}
//添加元素
env->SetIntArrayRegion(aa, 0, 10, tmp);
二维数组
jobjectArray result;
//创建对象数组
result = env->NewObjectArray(10,clazz,NULL);
jclass clazz = env->FindClass("[B");
jint tmp2[1024];//固定数组,注意别溢出
//jint *carr;
jintArray intArr;
for (int i = 0; i < 10; i++) {
intArr = env->NewIntArray(10-i);
//carr = env->GetIntArrayElements(intArr, NULL);
for (int j = 0; j < 10; j++) {
tmp2[j] = i + j;
//carr[j] = i + j;
}
//一维数组赋值
env->SetIntArrayRegion(intArr, 0, 10-i, tmp2);
//设置对象元素,result为目标数组,i是位置索引,intArr是byte数组
env->SetObjectArrayElement(result, i, intArr);
env->DeleteLocalRef(intArr);
}
jni读取二位数组
//posxy是float[][]
int len = env->GetArrayLength(posxy);
for (int i = 0; i < len; i++) {
jobject farray = env->GetObjectArrayElement(posxy, i);
int l = env->GetArrayLength((jfloatArray)farray);
//flaot[]转float*
jfloat *xy = env->GetFloatArrayElements((jfloatArray)farray, NULL);
for (int j = 0; j < l; j++) {
GLOGD("========>pfj: x|y=%.1f", xy[j]);
}
}
jni给java成员变量赋值
//class对象
jclass jclass_general = env->FindClass("com/pfj/demo/Response”);
//无参构造
jmethodID general_Constructor = env->GetMethodID(jclass_general, "<init>", “()V”);
//得到实例对象
jobject jobject_general = env->NewObject(jclass_general, general_Constructor);
//成员变量 names,类型是float[]
jfieldID jfield = env->GetFieldID(jclass_general, “names”,”[F”);
int size = 16;
jfloatArray jfloatArray = env->NewFloatArray(size);
//flaot[]转float*
jfloat *arr_temp = env->GetFloatArrayElements(jfloatArray, NULL);
for (int j = 0; j < size; j++) {
arr_temp[j] = j+100;//赋值
}
//jfloatArray赋值
env->SetFloatArrayRegion(jfloatArray, 0, size, arr_temp);
//java成员变量赋值
env->SetObjectField(jobject_general, jfield, jfloatArray);
env->DeleteLocalRef(jfloatArray); // free memory
2.关于FindClass
创建一个jclass的引用,创建int的class引用:jclass intClazz = env->FindClass(“com.xxx.xxx”);
其他类型:
Z boolean
B byte
C char
S short
I int
J long
F float
D double
[D double[]
Ljava/lang/String; String
[Ljava/lang/String; string[]
返回类实体数据:
public class Response {
public float score;
public int grade;
public double number;
public double[] corner;
public String result;
// public String result2[8];
}
jni返回Response[]对象数组:
static jobjectArray convert(JNIEnv *env, std::vector<Rersult> pv_responses) {
// 对象class
jclass jclass_general = env->FindClass("com/xxx/xxx/Response");
if (jclass_general == NULL) {
return NULL;
}
// 对象数组
jobjectArray jresponses = env->NewObjectArray(pv_responses.size(), jclass_general, NULL);
for (int i = 0; i < pv_responses.size(); ++i) {
// 构造方法ID
jmethodID general_Constructor = env->GetMethodID(jclass_general, "<init>", "()V");
if (general_Constructor == NULL) {
return NULL;
}
// 构造对象
jobject jobject_general = env->NewObject(jclass_general, general_Constructor);
if (jobject_general == NULL) {
return NULL;
}
// score
jfieldID score = env->GetFieldID(jclass_general, "score", "F");
if (score == NULL) {
return NULL;
}
env->SetFloatField(jobject_general, score, pv_responses[i].score);
// grade
jfieldID grade = env->GetFieldID(jclass_general,"grade", "I");
if (grade == NULL) {
return NULL;
}
env->SetIntField(jobject_general, l_t, pv_responses[i].grade);】
// number
jfieldID number = env->GetFieldID(jclass_general,"number", "D");
if (number == NULL) {
return NULL;
}
env->SetDoubleField(jobject_general, number, pv_responses[i].number);
// corner
jdoubleArray corner = env->NewDoubleArray(8); // 数组长度8
env->SetDoubleArrayRegion(corner, 0, 8, pv_responses[i].corner);
jfieldID cornerID = env->GetFieldID(jclass_general, "corner", "[D");
env->SetObjectField(jobject_general, cornerID, corner);
env->DeleteLocalRef(corner);
// result
jstring jstring_result = env->NewStringUTF(pv_responses[i].result.c_str()); // string转jstring
jfieldID jfield_result = env->GetFieldID(jclass_general, "result", "Ljava/lang/String;");
env->SetObjectField(jobject_general, jfield_result, jstring_result);
env->DeleteLocalRef(jstring_result);
// String数组待补充...
// 一个对象Response
env->SetObjectArrayElement(jresponses, i, jobject_general);
}
env->DeleteLocalRef(jclass_general);
return jresponses;
}
3.log打印
#define GLOGD(format, ...) fprintf(stdout, "[%s %s] " format "\n", __FILE__, \
__FUNCTION__, ##__VA_ARGS__)
#define GLOGI(format, ...) fprintf(stdout, "[%s %s] " format "\n", __FILE__, \
__FUNCTION__, ##__VA_ARGS__)
#define GLOGW(format, ...) fprintf(stdout, "[%s %s] " format "\n", __FILE__, \
__FUNCTION__, ##__VA_ARGS__)
#define GLOGE(format, ...) fprintf(stderr, "[%s %s] " format "\n", __FILE__, \
__FUNCTION__, ##__VA_ARGS__)
4. 异常处理
如果在native方法中发生了异常,通过下面这段代码抛出一个Java可以接收的异常
jclass errCls;
env->ExceptionDescribe();
env->ExceptionClear();
errCls = env->FindClass(“java/lang/IOException”);
//抛出一个Java可以接收的异常
env->ThrowNew(errCls, "thrown from C++ code");
如果要抛出其他类型的异常,替换掉FindClass的参数即可。