1,爲何須要類緩存:html
答:因爲頻繁的查找類及類成員變量須要很大的時間與空間開銷,可參考以下文章:java
http://www.ibm.com/developerworks/cn/java/j-jni/c++
http://www.28im.com/java/a2379737.html數組
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 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,c++端的相關實現代碼:函數
①定義一個對應的結構體:spa
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 };
②定義對應類的變量:code
struct JTestSetData gs_testSetDataMgr;
③實現緩存函數:htm
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 reference 20 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, "<init>", "()V"); 3 jobject jresult = env->NewObject(gs_testGetDataMgr.jtestGetData, initID);