JNI 玩转Java基本属性和对象

前景知识

Java,JNI,C++三者的关系

在这里插入图片描述
JNI是中转站,C++想要操作Java的数据,首先得第一条就是让JNI获取到Java的数据,也就是JAVA把数据传递给JNI,JNI经过一些列的处理,再传递给C++,
C++想把数据传递给Java,同样也需要通过JNI进行中转.Java与C++是相互分离的,不进行直接的交互

JNI和Java属性对应关系

JavaJNI
intjint
Stringjstring
booleanjboolean
bytejbyte
floatjfloat
doublejdouble

签名

Java签名
intI
booleanZ
byteB
floatF
doubleD
LangJ
StringLjava/lan/string;
objectLxxx/xxx/xxx;

前期准备文件

public class Student
{ private final static String TAG = Student.class.getSimpleName();

    public String name="杰克逊";
    public int age=18;
    public static int id = 0;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        Log.d(TAG, "Java setName name:" + name);
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        Log.d(TAG, "Java setAge age:" + age);
        this.age = age;
    }

    public static void showInfo(String info) {
        Log.d(TAG, "showInfo info:" + info);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Java的基本属性

在Java中有一个这样的方法

public native void testArrayAction(jobject student, int[] ints, String[] strs);

与之对应的C++方法是这样的

extern "C"//按照C标准进行编译
JNIEXPORT void JNICALL
Java_com_json_testjni2_MainActivity_testArrayAction//方法名
(JNIEnv *env, jobject thiz, jint count,jstring text_info, jintArray ints,jobjectArray strs)
 {}

我们的目的就是,操作传递过来的参数


extern "C"//按照C标准进行编译
JNIEXPORT void JNICALL
Java_com_json_testjni2_MainActivity_testArrayAction//方法名
(JNIEnv *env, jobject thiz, jint count,jstring text_info, jintArray ints,jobjectArray strs)
 {
   //操作属性

    //获取Student的Class
	jclass studentClass = env->GetObjectClass(student);
	//获取属性名   第一个参数是类名,第二个参数是属性名,第三个参数是签名
    jfieldID nameId = env->GetFieldID(studentClass, "name", "Ljava/lang/String;");
    //获取属性值
    jstring j_name = static_cast<jstring>(env->GetObjectField(student, nameId));
    //把JNI字符串转换成C++类型
    char *c_name = const_cast<char *>(env->GetStringUTFChars(j_name, NULL));
    LOGI("我是 string 类型参数 %s", str);//打印 这是一个宏定义  #define TAG "jason"  #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)


	//设置name值

	//把字符串转换成JNI类型
	jstring j_string = env->NewStringUTF("迈巴赫");
	//设置属性字符串 第一个参数是JNI类型的对象名,第二个阐述属性Id,第三个参数是Value
	env->SetObjectField(student, nameId, j_string);


	//操作方法


	//调用setName方法
	//获取方法Id   第一个参数:类名,第二个参数:方法名,第三个参数:方法签名
	jmethodID setName = env->GetMethodID(studentClass, "setName", "(Ljava/lang/String;)V");
    jstring j_string = env->NewStringUTF("冯家振");
    env->CallVoidMethod(studentObject, setName, j_string); //调用没有返回值得方法



	//调用 getName
	jmethodID getName = env->GetMethodID(studentClass, "getName", "()Ljava/lang/String;");
    jstring name = static_cast<jstring >(env->CallObjectMethod(studentObject, getName));
    char *c_name = const_cast<char *>(env->GetStringUTFChars(name, NULL));
    LOGI("我是 getName 参数 %s", c_name);


	//调用静态属性并赋值
	//获取静态属性ID
	jfieldID j_staticFieldId=env->GetStaticFieldID(studentClass,"id","I");
	//获取值
    jint j_int = env->GetStaticIntField(studentClass, j_staticFieldId);
    LOGI("我是 int 类型参数 %d", j_int);
	//设置值
    env->SetStaticIntField(studentClass, j_staticFieldId, 10);

	//调用静态方法
	jmethodID showInfo = env->GetStaticMethodID(studentClass, "showInfo", "(Ljava/lang/String;)V");
	jstring info = env->NewStringUTF("冯家振");
	env->CallStaticVoidMethod(studentClass, showInfo, info);
}

创建Java对象


extern "C"
JNIEXPORT void JNICALL
Java_com_json_testjni2_MainActivity_insertObject(JNIEnv *env, jobject thiz) {
    // TODO: implement insertObject()

    const char *studentPath = "com/json/testjni2/Student";
    jclass studentClass = env->FindClass(studentPath);

    //Alloc 只实例化对象,不会调用构造函数
   jobject studentObject=env->AllocObject(studentClass);

    jmethodID setName = env->GetMethodID(studentClass, "setName", "(Ljava/lang/String;)V");
    jstring j_string = env->NewStringUTF("冯家振");
    env->CallVoidMethod(studentObject, setName, j_string);

    jmethodID getName = env->GetMethodID(studentClass, "getName", "()Ljava/lang/String;");
    jstring name = static_cast<jstring >(env->CallObjectMethod(studentObject, getName));

    char *c_name = const_cast<char *>(env->GetStringUTFChars(name, NULL));
    LOGI("我是 getName 参数 %s", c_name);


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~搬~运~工~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值