JNI-获取Java对象的成员变量-GeInttField()

例:

在Java中定义一个属性,然后用C语言将其设置成另外的值,并输出出来。

Java代码:

Person.java

复制代码
package com.yuneec.demo;

public class Person {

    static {
        System.loadLibrary("td");
    }
    
    public int age = 20;
    
    public native void readAge();
    
    public int getAge() {
        return age;
    }
    
}
复制代码

MainActivity.java

复制代码
package com.yongdaimi.android.framework;

import com.yuneec.demo.Person;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener{


    private Button bt_test;
    private Person person;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt_test = (Button) findViewById(R.id.bt_test);
        bt_test.setOnClickListener(this);
        person = new Person();
    }
    
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.bt_test:
            // called by native
            person.readAge();
            // called by java
            int java_age = person.getAge();
            Log.i("xp.chen", "java_age is: "+java_age);
            break;
        default:
            break;
        }
    }
    
}
复制代码

C代码;

test_jni.c

复制代码
#ifdef __ANDROID__

#include <jni.h>
#include <android/log.h>
#include <stdio.h>
#include "jnihelp.h"

#define LOG_TAG "xp.chen"

#ifdef LOG_TAG
    #define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) 
#else
    #define LOGE(...)   
#endif


JNIEXPORT void com_yuneec_demo_Person_readAge(JNIEnv *env, jobject obj)
{
    //获致obj中对象的class
    jclass clazz = (*env)->GetObjectClass(env, obj);
    // 获取java中age字段的ID(最后一个参数是age的签名)
    jfieldID id_age = (*env)->GetFieldID(env, clazz, "age", "I");
    // 获取age字段对应的值
    jint age = (*env)->GetIntField(env, obj, id_age);
    // 输出
    // printf("current age is: %d\n", number);
    LOGE("native-age is: %d\n", age);
    // 重新修改age字段的值为100。
    (*env)->SetIntField(env, obj, id_age, 100);
}


static JNINativeMethod methods[] = {
     {"readAge","()V",(void*)com_yuneec_demo_Person_readAge},
};

static const char *classPathName = "com/yuneec/demo/Person";

static int registerNativeMethods(JNIEnv* env, const char* className,JNINativeMethod* gMethods, int numMethods)
{
    jclass clazz;

    clazz = (*env)->FindClass(env, className);
    if (clazz == NULL){
        return JNI_FALSE;
    }

   if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0)
    {
        return JNI_FALSE;
    }

    return JNI_TRUE;
}


void JNI_OnUnload(JavaVM* vm, void* reserved)
{
    return;
}

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    JNIEnv *env;
    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        return -1;
    }
    if (JNI_TRUE != registerNativeMethods(env, classPathName,methods, sizeof(methods) / sizeof(methods[0])))
    {
        return -1;
    }
    return JNI_VERSION_1_4;
}
#endif
复制代码

编译成功后,在eclipse中的运行结果为:

第一个是在C代码中读取到的Java中成员变量age的值。

第二个是在Java代码中读取到成员变量的值(在Native层作了修改)。 

 



如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   夜行过客  阅读(4725)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
历史上的今天:
2017-08-21 1.结构体和位运算
点击右上角即可分享
微信分享提示