使用jni直接访问java对象中的字段

Java类:UserInfo

public class UserInfo {
	static {
		System.loadLibrary("userinfo");
	}
	// 从JNI中直接访问字段
	public String mUserName;
	public int mUserAge;
	public long mMoney;

	public UserInfo() {

	}

	public int getUserAge() {
		return mUserAge;
	}

	public native void setUserName(String name);
	public native void setUserAge(int age);
	public native void setUserMoney(long money);
}

其中三个设置方法,期望使用C实现,这里涉及到JNI中的几个函数:

1、FindClass:找到某个类,并返回jclass对象

2、GetObjectClass: 获取到某个对象的类型,并返回jclass对象

3、GetFieldID:获取到字段的ID

4、SetIntField/SetLongField/SetObjectField:为字段设值

基于上面的几个方法,可以编写代码如下:

/*
 * Class:     com_iflytek_testjni_UserInfo
 * Method:    setUserName
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_iflytek_testjni_UserInfo_setUserName(JNIEnv *env, jobject obj, jstring jstr) {
	jfieldID fid;

	jclass cls = (*env)->GetObjectClass(env, obj);
	fid = (*env)->GetFieldID(env, cls, "mUserName", "Ljava/lang/String;");
	(*env)->SetObjectField(env, obj, fid, jstr);
}

/*
 * Class:     com_iflytek_testjni_UserInfo
 * Method:    setUserAge
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_iflytek_testjni_UserInfo_setUserAge(JNIEnv *env, jobject obj, jint age) {
	jclass objClass = (*env)->FindClass(env, "com/iflytek/testjni/UserInfo");
	jfieldID ageID = (*env)->GetFieldID(env, objClass, "mUserAge", "I");
	(*env)->SetIntField(env, obj, ageID, (int)age);
}

/*
 * Class:     com_iflytek_testjni_UserInfo
 * Method:    setUserMoney
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_com_iflytek_testjni_UserInfo_setUserMoney(JNIEnv *env, jobject obj, jlong money) {
	jclass objClass = (*env)->FindClass(env, "com/iflytek/testjni/UserInfo");
	jfieldID id = (*env)->GetFieldID(env, objClass, "mMoney", "J");
	(*env)->SetLongField(env, obj, id, (long)money);
}

编写Android.mk后编译,可以测试通过。

注意:由于方法签名、字段名称都是写死在C语言中的,因此代码不能混淆。

使用jni直接访问java对象中的字段,布布扣,bubuko.com

时间: 2025-01-01 08:45:05

使用jni直接访问java对象中的字段的相关文章

Android中关于JNI 的学习(三)在JNI层访问Java端对象

前面两篇文章简单介绍了JNI层跟Java层的一些对应关系,包括方法名,数据类型和方法名称等,相信在理论层面,能够很好地帮助我们去了解JNI在Native本地开发中的作用,对JNI的一些概念也有了一个初步的认识,由于表达能力或者理解还是有限,有些地方讲得不是很清楚,如果各位朋友有觉得云里雾里,欢迎大家留言一起学习. 概念上的理解有助于我们更好地认识JNI,而一些实际点的例子则能够更好地帮我们从代码上去掌握并应用JNI. 在第一篇文章,我们是从一个小例子来入门学习的,在其中,我们通过JNI层函数返回

OpenCV访问Mat对象中数据时发生异常---Mat中的数据访问

7.1和7.1.1由于越狱不成熟,半完美越狱后电脑上无法访问系统越狱目录,如var usr 等等. 今天有些意外地发现,可以在电脑上使用手机的越狱目录我手机 i4 7.1.1 联通 半完美越狱,没装Afc2Add,也没装Appsync 附上  --->我的半完美越狱过程 好了,下面直接正题 一.前提,必须安装ifile! 打开ifile,并转到 /var/mobile/media 目录下,然后点击右上角的 [ 编辑 ]如图: 二.点左下角的 + 号创建,如图: 三.点 [ 类型],选择[符号链接

数组对象如何根据对象中某个字段分组

场景:做报表图形展示时,接口返回的数据通常为一组数据对象,需要根据code进行分组,将数据分类成几组,用图形描绘出来 措施:代码如下 返回数组对象包括name和data两个字段,data中包括原数组对象中所有字段. function groupByType(arr,param) { var map = {}, dest = []; for(var i = 0; i < arr.length; i++){ var ai = arr[i]; if(ai[param] && !map[ai

apache commons JXPath 说明,使用JXPath访问java对象、集合和XML文件

Commons-JXPath 提供了使用Xpath语法操纵符合Java类命名规范的 JavaBeans的工具.也支持 maps, DOM 和其他对象模型.JXPath的主要功能在于一组java类库来使用XPath的方式访问符合JavaBeans规范的java类.java集合(Collections).其他具有动态属性的对象(如Map.ServletContext等),同时提供了一套扩展机制使我们可以增加对这些对象之外的其他对象模型的支持. 如果你要访问的属性不是这个Java类的属性,那么执行过程

因在缓存对象中增加字段,而导致Redis中取出缓存转化成Java对象时出现反序列化失败的问题

背景描述 因为业务需求的需要,我们需要在原来项目中的一个DTO类中新增两个字段(我们项目使用的是dubbo架构,这个DTO在A项目/服务的domain包中,会被其他的项目如B.C.D引用到).但是这个DTO对象已经在Redis缓存中存在了,如果我们直接向类中增加字段而不做任何处理的话,那么查询操作查出来的缓存对象就会报反序列化失败的错误,从而影响正常的业务流程,那么来看一下我的解决方案吧. 升级缓存版本号 我们的正式环境和预发布环境是共用Redis和Mysql.如果修改了DTO且没有加@Json

如何定制对象中特定字段的JSON输出内容

引言: 在Web应用开发中,经常需要将对象转化为JSON字符串的过程中,会有默认的输出内容不符合要求的情况,比如DateTime.一般可以通过定制Serializer来实现定制化的JSON字符输出. 1.  在对象中的getXXX方法中设置自定义的Serializer public class MyObject { private DateTime startDate; @JsonSerialize(using = DateTimeJsonSerializer.class) public Dat

Java获取类或对象中的字段名称和JsonProperty注释的名称

创建一个模型如下: package model; import com.fasterxml.jackson.annotation.JsonProperty; public class ProvNode { @JsonProperty("machineId") private String nodeId; private String name; private String result; private String status; @JsonProperty("messa

js 对象数组 根据对象中某个字段排序

第一种排序方式 var compare = function (prop) { return function (obj1, obj2) { var val1 = obj1[prop]; var val2 = obj2[prop]; if (val1 < val2) { return 1; } else if (val1 > val2) { return -1; } else { return 0; } } }; $scope.orderDrugMasterList.sort(compare(

快速更改对象中的字段名

问题描述: 有这样一个对象 let params = { id: 123, name: 'WiseWrong', e_mail: '[email protected]', tell: '12345678', } 由于种种原因,需要将其中的字段名  e_mail 修改为 eMail 分析原因: 处理的方案有很多,比如用 for-in 语句遍历,或者 delete 之后再新增字段,但这两种方案都有问题 首先 for-in 遍历效率太低,直接忽略.使用 delete 处理基础类型很有效,但字段的顺序会