android NDK 实用学习(一)-获取java端类及其类变量
近期为android 端项目包装一些c++代码,故学习ndk相关知识,现总结如下:
1,java与c++类型参照图:
2,此测试中使用的java类:
1 package com.dasea.test.core; 2 public class TestSetData { 3 // 主要是类ID和字段ID,方法ID的缓存 4 static { 5 OnNative(); 6 } 7 8 public native static void OnNative(); 9 10 public boolean bData; 11 public double dData; 12 public int iData; 13 public byte cData; 14 public String sData; 15 public byte byteArr[]; 16 17 public int intArr[]; 18 19 public TestSetData() { 20 // TODO Auto-generated constructor stub 21 bData = true; 22 dData = 100.11; 23 iData = 333; 24 cData = 100; 25 sData = "20150204"; 26 byteArr = new byte[10]; 27 for (int i = 0; i < byteArr.length; i++) { 28 byteArr[i] = '2'; 29 } 30 31 intArr = new int[10]; 32 for (int i = 0; i < intArr.length; i++) { 33 intArr[i] = i * 10; 34 } 35 } 36 }
3,使用类接口定义:
①java端:
public native TestSetData testData(TestSetData obj);
②c++端:
JNIEXPORT jobject JNICALL Java_com_dasea_test_core_JniDemo_testData(JNIEnv* env, jobject obj, jobject jobj) ;
4,完整c++端接口实现:
1 JNIEXPORT jobject JNICALL Java_com_dasea_test_core_JniDemo_testData(JNIEnv* env, jobject obj, jobject jobj){ 2 DEBUG_OUT("test set data start"); 3 4 jclass jcSetDataMgr = env->FindClass("com/dasea/test/core/TestSetData"); 5 if(NULL == jcSetDataMgr){ 6 DEBUG_OUT("Not find class!"); 7 return NULL; 8 } 9 DEBUG_OUT("Find class succ!"); 10 11 jfieldID jfbdata = env->GetFieldID(jcSetDataMgr, "bData", "Z"); 12 if(NULL == jfbdata){ 13 DEBUG_OUT("jfbdata fail!"); 14 } 15 jfieldID jfddata = env->GetFieldID(jcSetDataMgr, "dData", "D"); 16 if(NULL == jfbdata){ 17 DEBUG_OUT("jfddata fail!"); 18 } 19 jfieldID jfidata = env->GetFieldID(jcSetDataMgr, "iData", "I"); 20 if(NULL == jfbdata){ 21 DEBUG_OUT("jfidata fail!"); 22 } 23 jfieldID jfcdata = env->GetFieldID(jcSetDataMgr, "cData", "B"); 24 if(NULL == jfbdata){ 25 DEBUG_OUT("jfcdata fail!"); 26 } 27 jfieldID jfsdata = env->GetFieldID(jcSetDataMgr, "sData", "Ljava/lang/String;"); 28 if(NULL == jfbdata){ 29 DEBUG_OUT("jfsdata fail!"); 30 } 31 32 DEBUG_OUT("Get end!"); 33 34 env->SetBooleanField(jobj, jfbdata, false); 35 DEBUG_OUT("SetBooleanField end!"); 36 37 env->SetDoubleField(jobj, jfddata, 209.22); 38 DEBUG_OUT("SetDoubleField end!"); 39 40 env->SetIntField(jobj, jfidata, 3653); 41 DEBUG_OUT("SetIntField end!"); 42 43 env->SetByteField(jobj, jfcdata, 67); 44 DEBUG_OUT("Set field succ!"); 45 46 char data[10] = "4611354"; 47 env->SetObjectField(jobj, jfsdata, env->NewStringUTF(data)); 48 49 jfieldID jiarr = env->GetFieldID(jcSetDataMgr, "intArr", "[I"); 50 if(NULL == jiarr){ 51 DEBUG_OUT("jfbdata fail!"); 52 } 53 54 // 获取Java中数组属性arrays的对象 55 jintArray jint_arr = (jintArray)env->GetObjectField(jobj, jiarr); 56 57 int arrInt[10] = {0}; 58 for(int i = 0; i < 10; ++i){ 59 arrInt[i] = 220+i; 60 } 61 env->SetIntArrayRegion(jint_arr, 0, 10, arrInt); 62 63 jfieldID jbyteArr = env->GetFieldID(jcSetDataMgr, "byteArr", "[B"); 64 char arrByte[10] = "20200825"; 65 jbyteArray jbyte_arr = (jbyteArray)env->GetObjectField(jobj, jbyteArr); 66 env->SetByteArrayRegion(jbyte_arr, 0, 8, (const signed char*)arrByte); 67 68 DEBUG_OUT("test set data end!"); 69 70 return NULL; 71 }
5,单独讲解:
①查找java类:
jclass jcSetDataMgr = env->FindClass("com/dasea/test/core/TestSetData");
②查找类成员变量:
1 jfieldID jfbdata = env->GetFieldID(jcSetDataMgr, "bData", "Z"); 2 jfieldID jfddata = env->GetFieldID(jcSetDataMgr, "dData", "D"); 3 jfieldID jfidata = env->GetFieldID(jcSetDataMgr, "iData", "I"); 4 jfieldID jfcdata = env->GetFieldID(jcSetDataMgr, "cData", "B"); 5 jfieldID jfsdata = env->GetFieldID(jcSetDataMgr, "sData", "Ljava/lang/String;"); 6 jfieldID jbyteArr = env->GetFieldID(jcSetDataMgr, "byteArr", "[B"