本地C代码中创建Java对象
作者:唐老师,华清远见嵌入式学院讲师。
创建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对象的更多相关文章
- Java中JNI的使用详解第四篇:C/C++中创建Java对象和String字符串对象及对字符串的操作方法
首先来看一下C/C++中怎么创建Java对象:在JNIEnv中有两种方法是用来创建Java对象的: 第一种方法: jobject NewObject(jclass clazz , jmethodI ...
- IntelliJ IDEA平台下JNI编程(五)—本地C代码创建Java对象及引用
本文学习如何在C代码中创建Java对象和对象数组,前面我们学习了C代码中访问Java对象的属性和方法,其实在创建对象时本质上也就是调用构造函数,因此本文知识学习起来也很轻松.有了前面学习数组创建的方法 ...
- Java中创建实例化对象的几种方式
Java中创建实例化对象有哪些方式? ①最常见的创建对象方法,使用new语句创建一个对象.②通过工厂方法返回对象,例:String s =String.valueOf().(工厂方法涉及到框架)③动用 ...
- Java中创建的对象多了,必然影响内存和性能
1, Java中创建的对象多了,必然影响内存和性能,所以对象的创建越少越好,最后还要记得销毁.
- 在Android Native层中创建Java虚拟机实例
前言 Android应用中JNI代码,是作为本地方法运行的.而大部分情况下,这些JNI方法均需要传递Dalvik虚拟机实例作为第一个参数.例如,你需要用虚拟机实例来创建jstring和其他的Java对 ...
- JNI_Z_08_创建Java对象
1.步骤 : (1).获取 jclass (2).获取 构造函数的 method id (方法的名称始终为"<init>") (3).创建Java对象的两种方式: (3 ...
- 本地代码中使用Java对象
通过使用合适的JNI函数,你可以创建Java对象,get.set 静态(static)和 实例(instance)的域,调用静态(static)和实例(instance)函数.JNI通过ID识别域和方 ...
- JavaScript中创建字典对象(dictionary)实例
这篇文章主要介绍了JavaScript中创建字典对象(dictionary)实例,本文直接给出了实现的源码,并给出了使用示例,需要的朋友可以参考下 对于JavaScript来说,其自身的Array对象 ...
- 除了使用new关键字,还有什么方法可以创建Java对象呢?
今天来盘点一下除了使用 "new" 关键字创建对象,还有什么方法可以创建Java对象呢? 因为是创建对象,所以这里ioc容器不在范围内 我们先看一下常用的new关键字创建 Clas ...
随机推荐
- Oracle【IT实验室】数据库备份与恢复之五:Flashback
Flashback在开发环境(有时生产环境的特殊情况下)是很有用的一个工具. 5.1 9i Flashback 简介 5.1.1 原理 当数据 update 或 delete ...
- 用Node.js开发Windows 10物联网应用
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 未来10年内,物联网将会如移动互联网这样深入到我们生活的各方各面.所以微软现在对物联网进行了 ...
- java-xml格式化
参考:http://www.oschina.net/code/snippet_17793_4733 package com.ddatsh; import java.io.IOException; ...
- UVA232字符串处理
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> ...
- Callable接口、Runable接口、Future接口
1. Callable与Runable区别 Java从发布的第一个版本开始就可以很方便地编写多线程的应用程序,并在设计中引入异步处理.Thread类.Runnable接口和Java内存管理模型使得多线 ...
- DampView阻尼效果
阻尼效果即是图片向下拉动时会放大,松开会回弹 1.自定义一个DampView类,继承ScrollView 2.布局最外层必须是DampView,且DampView和要拉动的图片之间只能有一层layou ...
- 记录java基础的学习过程
标识符(类名:变量.属性.方法名: ) 组成:类名开头不能是数字,只能有字母数字_$组成. 命名规范: 类名每一个单词首字母大写(HelloWorld大驼峰法则), 方法名 属性名 变量名首字母小写之 ...
- 数值的三种表示--C语言
在C语言中,数值常数可以是3中形式: (1)在数值前面加0表示的是8进制数据: (2)在数字前面加0x表示的是16进制数: (3)在数值前面什么也不加,表示的是10进制数值. 目前C语言 ...
- windows修改虚拟内存
右键电脑属性: 高级系统设置: 性能设置: 虚拟内存更改:
- CSS3_实现圆角效果box-shadow
1.outline的直角与圆角 来给个div: <div class="use-outline"></div> 来再给个样式: .use-outline{ ...