android NDK 入门之在JNI中修改java中对象的成员变量的值
如题:测试在JNI中修改java代码中成员变量的值
JavaBean类编写如下
package com.xl.qiu;
public class StepByStepInstance {
public native void changeStepInstanceString();
public StepByStepInstance(String str1)
{
this.str1 = str1;
}
private String str1;
public String getStr1() {
return str1;
}
public void setStr1(String str1) {
this.str1 = str1;
}
}
调用处Java代码如下:
StepByStepInstance step = new StepByStepInstance("step");
step.changeStepInstanceString();
javah 工具生成.h头文件如下:
#include <jni.h>
/* Header for class com_xl_qiu_StepByStepInstance */
#ifndef _Included_com_xl_qiu_StepByStepInstance
#define _Included_com_xl_qiu_StepByStepInstance
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_xl_qiu_StepByStepInstance
* Method: changeStepInstanceString
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_xl_qiu_StepByStepInstance_changeStepInstanceString
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
编写c语言代码如下:
JNIEXPORT void JNICALL Java_com_xl_qiu_StepByStepInstance_changeStepInstanceString(JNIEnv *env, jobject this) {
jfieldID fid;
jstring jstr;
const char *str;
jclass cls = (*env)->GetObjectClass(env, this);
fid = (*env)->GetFieldID(env, cls, "str1", "Ljava/lang/String;");
if (fid == NULL)
return;
jstr = (*env)->GetObjectField(env, this, fid);
str = (*env)->GetStringUTFChars(env, jstr, NULL);
if (str == NULL)
return;
__android_log_print(ANDROID_LOG_INFO, "JNI", "In C Str:%s, Change in StepByStepInstance.java", str);
(*env)->ReleaseStringUTFChars(env, jstr, str);
jstr = (*env)->NewStringUTF(env, "New String Given By C, Change field int StepByStepInstance.java");
if (jstr == NULL)
return;
(*env)->SetObjectField(env, this, fid, jstr);
}
简单解释一下JNI代码中几个调用的函数:
GetObjectClass
jclassGetObjectClass(JNIEnv*env,jobjectobj);
返回对象的类。
参数:
env:JNI接口指针。
obj:Java对象(不能为NULL)。
返回值:
返回Java类对象。
GetFieldID
jfieldIDGetFieldID(JNIEnv*env,jclassclazz,
constchar*name,constchar*sig);
返回类的实例(非静态)域的域ID。该域由其名称及签名指定。访问器函数的Get<type>Field及Set<type>Field系列使用域ID检索对象域。
GetFieldID()将未初始化的类初始化。
GetFieldID()不能用于获取数组的长度域。应使用GetArrayLength()。
参数:
env:JNI接口指针。
clazz:Java类对象。
name:0终结的UTF-8字符串中的域名。
sig:0终结的UTF-8字符串中的域签名。
返回值:
域ID。如果操作失败,则返回NULL。
Get<type>Field例程
NativeTypeGet<type>Field(JNIEnv*env,jobjectobj,
jfieldIDfieldID);
该访问器例程系列返回对象的实例(非静态)域的值。要访问的域由通过调用GetFieldID()而得到的域ID指定。
Set<type>Field例程
voidSet<type>Field(JNIEnv*env,jobjectobj,jfieldIDfieldID,
NativeTypevalue);
NewStringUTF
jstringNewStringUTF(JNIEnv*env,constchar*bytes);
利用UTF-8字符数组构造新java.lang.String对象。
参数:
env:JNI接口指针。如果无法构造该字符串,则为NULL。
bytes:指向UTF-8字符串的指针。
返回值:
Java字符串对象。如果无法构造该字符串,则为NULL。
ReleaseStringUTFChars
voidReleaseStringUTFChars(JNIEnv*env,jstringstring,
constchar*utf);
通知虚拟机平台相关代码无需再访问utf。utf参数是一个指针,可利用GetStringUTFChars()从string获得。
参数:
env:JNI接口指针。
string:Java字符串对象。
utf:指向UTF-8字符串的指针。
如上介绍了如何修改类成员变量(非静态,下面继续介绍如何修改静态类成员变量):
同样是StepByStepInstance类
我们添加类静态成员public static int static_i;
同样添加一个本地方法用来JNI修改static_i;
public native void changeStaticField();
.h文件中增加了方法声明:
JNIEXPORT void JNICALL Java_com_xl_qiu_StepByStepInstance_changeStaticField
(JNIEnv *, jobject);
c语言代码实现如下:
JNIEXPORT void JNICALL
Java_com_xl_qiu_StepByStepInstance_changeStaticField(
JNIEnv *env,
jobject this)
{
jfieldID fid;
jint si;
jclass cls = (*env)->GetObjectClass(env, this);
fid = (*env)->GetStaticFieldID(env, cls, "static_i", "I");
if (fid == NULL)
return;
si = (*env)->GetStaticIntField(env, cls, fid);
__android_log_print(ANDROID_LOG_INFO, "JNI", "In C Str:%d, given by StepByStepInstance.java", si);
(*env)->SetStaticIntField(env, cls, fid, ++si);
}
JNI函数介绍:
SetStatic<type>Field例程
voidSetStatic<type>Field(JNIEnv*env,jclassclazz,
jfieldIDfieldID,NativeTypevalue);
该访问器例程系列设置对象的静态域的值。要访问的域由通过调用GetStaticFieldID()而得到的域ID指定。
GetStatic<type>Field例程
NativeTypeGetStatic<type>Field(JNIEnv*env,jclassclazz,
jfieldIDfieldID);
该访问器例程系列返回对象的静态域的值。要访问的域由通过调用GetStaticFieldID()而得到的域ID指定。
上述JNI代码中用到了字段描述符:
一个特殊的 C字符串“Ljava/lang/String”来代表一个JVM 中的字段类
型。这个字符串被称为JNI field descriptor(字段描述符)。
字符串的内容由字段被声明的类型决定。例如,使用“I”来表示一个int类型的字段,“F”
来表示一个float类型的字段,“D”来表示一个double 类型的字段,“Z”来表示一个 boolean
类型的字段等等。
像java.lang.String这样的引用类型的描述符都是以L开头,后面跟着一个JNI类描述符,以
分号结尾。一个JAVA 类的全名中的包名分隔符“.”被转化成“/”。因此,对于一个字段类
型的字段来说,它的描述符是“Ljava/lang/String”。 数组的描述符中包含“]”字符
分享到:
相关推荐
Android NDK 开发时需要的 常用的JNI API
安卓app开发之NDK入门教程,JAVA代码通过JNI接口调用NDK代码(C语言编写的linux android功能).zip
Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例
android NDK的配置,JNI的使用及demoandroid NDK的配置,JNI的使用及demo
android NDK 自动生成jni头文件 要所java 类自动生成jni调用头文件。
Android JNI中C++层与Java层的对象交互实例代码详细介绍。Android JNI中C++层与Java层的对象交互实例代码详细介绍。Android JNI中C++层与Java层的对象交互实例代码详细介绍。Android JNI中C++层与Java层的对象交互...
Android NDK 开发教程及JNI教程c语言开发介绍
Android NDK入门
AndroidStudio环境下的jni调用(NDK),这个教程可以让完全不会AndroidStudio的人学会jni调用。完全步骤话,非常简单。
android jni NDK 经典入门
这是Android NDK开发标准的JNI和Android.mk编写模版,里面的一些东西可能涉及我的项目,但不影响观看
史上最强NDK入门项目实战.rar ndk入门很好的资料附代码
JNI入门Demo3.0,用于演示JNI中是如何动态注册Native函数。
Android NDK编程,我的第一个hello-jni程序,如何调用自己编译的so库 博客地址:http://blog.csdn.net/dqksky/article/details/40425977
事隔3年,把JNI的规范重新整理了一下。希望能给大家带来帮助
该资源包含了一个AndroidNDK入门项目实战,包括代码和注释,简单易懂!
android ndk举例 jni
Android NDK jni使用,包括java调用,脚本编写,和C++代码实现
Android-NDK-MD5-安卓jni 进行md5加密; Android-NDK-MD5-安卓jni 进行md5加密
超强NDK入门项目实战 你只知道 用java编 android吗 试试 c语言的吧 android 游戏必学