android NDK 实用学习(四)-类缓存

1,为什么需要类缓存:

答:由于频繁的查找类及类成员变量需要很大的时间与空间开销,可参考如下文章:

http://www.ibm.com/developerworks/cn/java/j-jni/

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++端的相关实现代码:

①定义一个对应的结构体:

 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 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);

 

posted @ 2015-07-01 11:54  殇 离  阅读(625)  评论(0编辑  收藏  举报