作者:唐老师,华清远见嵌入式学院讲师。

创建Java域的对象就是创建Java类的实例,再调用Java类的构造方法。

以Bitmap的构建为例,Bitmap中并没有Java对象创建的代码及外部能访问的构造方法,所以它的实例化必然是在JNI的c中实现的。

BitmapFactory.java中提供了得到Bitmap的方法,时序简化为:

BitmapFactory.java ->BitmapFactory.cpp ->

GraphicsJNI::createBitmap() [graphics.cpp]

GraphicsJNI::createBitmap()[graphics.cpp]的实现:

[cpp] view plaincopy
        1. jobjectGraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable,
        2. jbyteArray ninepatch, intdensity)
        3. {
        4.         SkASSERT(bitmap != NULL);
        5.         SkASSERT(NULL != bitmap->pixelRef());
        6.
        7.         jobject obj =env->AllocObject(gBitmap_class);
        8.         if (obj) {
        9.                 env->CallVoidMethod(obj,gBitmap_constructorMethodID,
        10.                 (jint)bitmap,isMutable, ninepatch, density);
        11.                 if (hasException(env)) {
        12.                         obj = NULL;
        13.                 }
        14.         }
        15.         return obj;
        16. }

而gBitmap_class的得到是通过:

2. gBitmap_class =(jclass)env->NewGlobalRef(c);
        3. //gBitmap_constructorMethodID是Bitmap的构造方法(方法名用”<init>”)的jmethodID:
        4. gBitmap_constructorMethodID= env->GetMethodID(gBitmap_class, "<init>",
        5. "(IZ[BI)V");

总结一下,c中如何访问Java对象的属性:
        1) 通过JNIEnv::FindClass()找到对应的jclass;
        2) 通过JNIEnv::GetMethodID()找到类的构造方法的jfieldID;
        3) 通过JNIEnv::AllocObject创建该类的对象;
        4) 通过JNIEnv::CallVoidMethod()调用Java对象的构造方法。

本地JNI对象的保存

c域中某次被调用生成的对象,在其他函数调用时是不可见的,虽然可以设置全局变量但那不是好的解决方式,Android中通常是在Java域中定义一个int型的变量,在c域生成对象的地方,与这个Java域的变量关联,在别的使用到的地方,在从这个变量中取值。

以JNICameraContext为例来说明:

JNICameraContext是android_hardware_camera.cpp中定义的类型,并会在cpp中生成对象,与Java中android.hardware.Camera的mNativeContext关联。

在注册native函数之前,c中就已经把Java域中的属性的jfieldID得到了。通过下列方法

2. jfieldID field = env->GetFieldID(clazz, " mNativeContext","I");

如果执行成功,把field保存到上面图中的fileds变量的context:jfieldID中。

生成cpp对象时,通过JNIEnv::SetIntField()设置为Java对象的属性

[cpp] view plaincopy
        1. static void android_hardware_Camera_native_setup(JNIEnv *env, jobjectthiz,
        2. jobject weak_this, jintcameraId)
        3. {
        4.         // …
        5.
        6.         // We use a weak reference sothe Camera object can be garbage collected.
        7.         // The reference is only used asa proxy for callbacks.
        8.         spcontext = new JNICameraContext(env, weak_this, clazz, camera);
        9.         // …
        10.         // 该处通过context.get()得到context对象的地址,保存到了Java中的mNativeContext属性里
        11.         env->SetIntField(thiz,fields.context, (int)context.get());
        12. }

而要使用时,又通过JNIEnv::GetIntField()获取Java对象的属性,并转化为JNICameraContext类型:

[cpp] view plaincopy
        1. JNICameraContext* context
=reinterpret_cast<JNICameraContext*>(env->GetIntField(thiz,
fields.context));
        2. if (context != NULL) {
        3. // …
        4. }

总结一下,c++中生成的对象如何保存和使用:
        1) 通过JNIEnv::FindClass()找到对应的jclass;
        2) 通过JNIEnv::GetFieldID()找到类中属性的jfieldID;
        3) 某个调用过程中,生成cpp对象时,通过JNIEnv::SetIntField()设置为Java对象的属性;
        4) 另外的调用过程中,通过JNIEnv::GetIntField()获取Java对象的属性,再转化为真实的对象类型。

文章来源:华清远见嵌入式学院;原文地址:http://www.embedu.org/Column/Column881.htm

更多相关嵌入式免费资料查看华清远见讲师博文>>

本地C代码中创建Java对象的更多相关文章

  1. Java中JNI的使用详解第四篇:C/C++中创建Java对象和String字符串对象及对字符串的操作方法

    首先来看一下C/C++中怎么创建Java对象:在JNIEnv中有两种方法是用来创建Java对象的: 第一种方法: jobject  NewObject(jclass clazz  , jmethodI ...

  2. IntelliJ IDEA平台下JNI编程(五)—本地C代码创建Java对象及引用

    本文学习如何在C代码中创建Java对象和对象数组,前面我们学习了C代码中访问Java对象的属性和方法,其实在创建对象时本质上也就是调用构造函数,因此本文知识学习起来也很轻松.有了前面学习数组创建的方法 ...

  3. Java中创建实例化对象的几种方式

    Java中创建实例化对象有哪些方式? ①最常见的创建对象方法,使用new语句创建一个对象.②通过工厂方法返回对象,例:String s =String.valueOf().(工厂方法涉及到框架)③动用 ...

  4. Java中创建的对象多了,必然影响内存和性能

    1, Java中创建的对象多了,必然影响内存和性能,所以对象的创建越少越好,最后还要记得销毁.

  5. 在Android Native层中创建Java虚拟机实例

    前言 Android应用中JNI代码,是作为本地方法运行的.而大部分情况下,这些JNI方法均需要传递Dalvik虚拟机实例作为第一个参数.例如,你需要用虚拟机实例来创建jstring和其他的Java对 ...

  6. JNI_Z_08_创建Java对象

    1.步骤 : (1).获取 jclass (2).获取 构造函数的 method id (方法的名称始终为"<init>") (3).创建Java对象的两种方式: (3 ...

  7. 本地代码中使用Java对象

    通过使用合适的JNI函数,你可以创建Java对象,get.set 静态(static)和 实例(instance)的域,调用静态(static)和实例(instance)函数.JNI通过ID识别域和方 ...

  8. JavaScript中创建字典对象(dictionary)实例

    这篇文章主要介绍了JavaScript中创建字典对象(dictionary)实例,本文直接给出了实现的源码,并给出了使用示例,需要的朋友可以参考下 对于JavaScript来说,其自身的Array对象 ...

  9. 除了使用new关键字,还有什么方法可以创建Java对象呢?

    今天来盘点一下除了使用 "new" 关键字创建对象,还有什么方法可以创建Java对象呢? 因为是创建对象,所以这里ioc容器不在范围内 我们先看一下常用的new关键字创建 Clas ...

随机推荐

  1. C语言面试

    最全的C语言试题总结 第一部分:基本概念及其它问答题 1.关键字static的作用是什么? 这个简单的问题很少有人能回答完全.在C语言中,关键字static有三个明显的作用: 1). 在函数体,一个被 ...

  2. ADT开发AndroidManifest.xml file missing错误

    一个错误“AndroidManifest.xml file missing”但helloworld目录下有此文件,几番google仍没能解决.想起曾经在网络上看到的一个修复project的办法,抱着死 ...

  3. loj 1316(spfa预处理+状压dp)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27024 题意:求0-(n-1)的经过最多的标记的点的最短路. 思路 ...

  4. WINDOWS系统下四叶草CLOVER引导U盘制作

    一.所需软件1.下载BootDiskUtility链接:http://pan.baidu.com/s/1bwBFyu 密码:glyk 2.下载Clover r3330 USB链接:http://pan ...

  5. 【转】HBase原理和设计

    简介 HBase —— Hadoop Database的简称,Google BigTable的另一种开源实现方式,从问世之初,就为了解决用大量廉价的机器高速存取海量数据.实现数据分布式存储提供可靠的方 ...

  6. 遭遇OutOfMemoryError

    这几天,网店系统基础架构进行了一次大的升级,升级之后例行的进行了压力测试,以前几次大的项目发布压力测试都没有任何问题,没想到这次出事故啦,而且是内存泄露? 系统运行环境:硬件:Intel(R) Xeo ...

  7. SpringHttpInvoker解析3-客户端实现

    主要的配置文件 <bean id="httpInvokerUserService" class="org.springframework.remoting.http ...

  8. POJ 3294 后缀数组

    题目链接:http://poj.org/problem?id=3294 题意:给定n个字符串,求一个最长子串要求在超过一半的字符串中出现过. 如果多解按字典序输出 思路:根据<<后缀数组— ...

  9. express-8 Handlebars模板引擎(1)

    简介 使用JavaScript生成一些HTML document.write('<h1>Please Don\'t Do This</h1>'); document.write ...

  10. Asp.net mvc 有关序列化的问题

    //            $.ajax({//                async: false,//                type:'post',//这里注意,Get请求不安全,用 ...