1,为什么需要类缓存:
答:由于频繁的查找类及类成员变量需要很大的时间与空间开销,可参考如下文章:
2,缓存时需要在java类使用static,如下:
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 stub21 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,c++端的相关实现代码:
①定义一个对应的结构体:
1 struct JTestSetData{ 2 jclass jtestSetData; 3 4 jfieldID jbData; 5 jfieldID jiData; 6 jfieldID jdData; 7 jfieldID jcData; 8 jfieldID jsData; 9 jfieldID jarrData;10 };
②定义对应类的变量:
struct JTestSetData gs_testSetDataMgr;
③实现缓存函数:
1 JNIEXPORT void JNICALL Java_com_dasea_test_core_TestSetData_OnNative(2 JNIEnv* env, jobject obj){3 DEBUG_OUT("TestSetData native start!");4 5 InitTestSetData(env);6 7 DEBUG_OUT("TestSetData native end!");8 }
1 bool InitTestSetData(JNIEnv* env){ 2 // 缓存类及其字段 3 // 查找类里面的字段,并进行赋值 4 5 // STEP 1/3 : Load the class id 6 jclass jcSetDataMgr = env->FindClass("com/kq/rtk/core/TestSetData"); 7 8 // STEP 2/3 : Assign the ClassId as a Global Reference 9 gs_testSetDataMgr.jtestSetData = (jclass) env->NewGlobalRef(jcSetDataMgr);10 11 jfieldID funB = env->GetFieldID(jcSetDataMgr, "bData", "Z");12 gs_testSetDataMgr.jbData = funB;13 gs_testSetDataMgr.jiData = env->GetFieldID(jcSetDataMgr, "iData", "I");14 gs_testSetDataMgr.jdData = env->GetFieldID(jcSetDataMgr, "dData", "D");15 gs_testSetDataMgr.jcData = env->GetFieldID(jcSetDataMgr, "cData", "B");16 gs_testSetDataMgr.jsData = env->GetFieldID(jcSetDataMgr, "sData", "Ljava/lang/String;");17 gs_testSetDataMgr.jarrData = env->GetFieldID(jcSetDataMgr, "intArr", "[I");18 19 // STEP 3/3 : Delete the no longer needed local reference20 env->DeleteLocalRef(jcSetDataMgr);21 22 return true;23 }
④使用缓存的类及成员:
java端接口:
public native void testPreCacheFun(TestSetData obj);
c++端实现:
1 JNIEXPORT void JNICALL Java_com_dasea_test_core_RTKNativeManager_testPreCacheFun( 2 JNIEnv* env, jobject obj, jobject jobj){ 3 DEBUG_OUT("testPreCache start!"); 4 5 if (NULL == gs_testSetDataMgr.jtestSetData) { 6 DEBUG_OUT("No cache class!"); 7 if(false == InitTestSetData(env)){ 8 DEBUG_OUT("Cache failed!"); 9 return ;10 }11 DEBUG_OUT("Cache success!");12 }else{13 DEBUG_OUT("Has cache!");14 }15 16 env->SetBooleanField(jobj, gs_testSetDataMgr.jbData, false);17 env->SetDoubleField(jobj, gs_testSetDataMgr.jdData, 209.22);18 env->SetIntField(jobj, gs_testSetDataMgr.jiData, 3653);19 env->SetByteField(jobj, gs_testSetDataMgr.jcData, 67);20 21 DEBUG_OUT("Set field succ!");22 23 char data[10] = "jfkdsajfl";24 jstring sss = env->NewStringUTF(data);25 env->SetObjectField(jobj, gs_testSetDataMgr.jsData, sss);26 env->DeleteLocalRef(sss);27 28 // 获取Java中数组属性arrays的对象29 jintArray jint_arr = (jintArray)env->GetObjectField(jobj, gs_testSetDataMgr.jarrData);30 int arrInt[10] = { 0};31 for(int i = 0; i < 10; ++i){32 arrInt[i] = 300+i;33 }34 env->SetIntArrayRegion(jint_arr, 0, 10, arrInt);35 36 DEBUG_OUT("testPreCache end!");37 }
⑤使用缓存类构造类对象:
1 DEBUG_OUT("AllocObject object !");2 jmethodID initID = env->GetMethodID(gs_testGetDataMgr.jtestGetData, "", "()V");3 jobject jresult = env->NewObject(gs_testGetDataMgr.jtestGetData, initID);