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);
时间: 2024-10-23 11:59:30

android NDK 实用学习(四)-类缓存的相关文章

android NDK 实用学习(三)- java端类对象的构造及使用

1,读此文章前我假设你已经读过: android NDK 实用学习-获取java端类及其类变量 android NDK 实用学习-java端对象成员赋值和获取对象成员值 2,java端类对象的构造: ①首先获取类; ②获取类的无参构造函数: jmethodID initID = env->GetMethodID(jcSetDataMgr, "<init>", "()V"); ③构造类实例: jobject jresult = env->New

android NDK 实用学习(五)-c++端调用java接口

1,阅读此文章前请阅读前面文章,以免阅读出现障碍: android NDK 实用学习(一)-获取java端类及其类变量 android NDK 实用学习(二)-java端对象成员赋值和获取对象成员值 android NDK 实用学习(三)- java端类对象的构造及使用 android NDK 实用学习(四)-类缓存 2,java端类接口定义: 1 public class RTKNativeManager { 2 // 其他接口 3 4 // 开给c++端的接口 5 public static

android NDK 实用学习-java端对象成员赋值和获取对象成员值

1,关于java端类及接口定义请参考: android NDK 实用学习-获取java端类及其类变量 2,对传过来的参数进行赋值: 对bool类型成员进行赋值  env->SetBooleanField(jobj, jfbdata, false); 对double类型成员进行赋值 env->SetDoubleField(jobj, jfddata, 209.22); 对int类型成员进行赋值 env->SetIntField(jobj, jfidata, 3653); 对byte类型成员

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

基于 Android NDK 的学习之旅----- C调用Java

http://www.cnblogs.com/luxiaofeng54/archive/2011/08/17/2142000.html 基于 Android NDK 的学习之旅----- C调用Java许多成熟的C引擎要移植到Android 平台上使用 , 一般都会 提供 一些接口, 让Android sdk 和 jdk 实现. 下文将会介绍 C 如何 通过 JNI 层调用 Java 的静态和非静态方法. 1.主要流程 1.  新建一个测试类TestProvider.java a)       

【转】基于 Android NDK 的学习之旅-----数据传输(引用数据类型)

原文网址:http://www.cnblogs.com/luxiaofeng54/archive/2011/08/20/2147086.html 基于 Android NDK 的学习之旅-----数据传输二(引用数据类型)(附源码) 基于 Android NDK 的学习之旅-----数据传输(引用数据类型) 接着上篇文章继续讲.主要关于引用类型的数据传输,本文将介绍字符串传输和自定义对象的传输. 1.主要流程 1.  String 字符串传输 a)         上层定义一个native的方法

Android Camera fw学习(四)-recording流程分析

Android Camera fw学习(四)-recording流程分析 备注:备注:本文是Android5.1学习笔记.博文按照软件启动流程分析.  且行且惜,一步一个脚印,这次学习camera Video.虽然标题是recording流程分析,但这里很多和preview是相似的(包含更新,创建Stream,创建Request),这里主要分析MediaRecorder对象创建.video帧监听对象注册.帧可用事件以及一系列callback流程分析. 一.认识video(mediaRecorde

基于 Android NDK 的学习之旅-----序言

http://www.cnblogs.com/luxiaofeng54/tag/android/default.html?page=1 基于 Android NDK 的学习之旅-----目录 duicky 2011-09-15 16:34 阅读:3035 评论:2 基于 Android NDK 的学习之旅-----资源释放 duicky 2011-08-21 14:29 阅读:6173 评论:0 基于 Android NDK 的学习之旅-----数据传输二(引用数据类型)(附源码) duicky

Android NDK 开发(四)java传递数据到C【转】

转载请注明出处:http://blog.csdn.net/allen315410/article/details/41845701 前面几篇文章介绍了Android NDK开发的简单概念.常见错误及处理和从第一个Hello World开始实际做一个简单的JNI开发示例,相信看完之后,大家对NDK开发有了一个概念上的认识了,那么接下来我们需要再深入一下NDK的开发,我们知道NDK开发就是使用JNI这层“协议”在Java和C之间起个“桥梁”的作用,将Java和Native C之间联立起来,让Java