JNI入门课程-第四章:JNI更改java对象属性值以及调用方法

 序章:

1.本篇是JNI入门教程的第四篇,完整教程连接如下:

https://blog.csdn.net/rzleilei/article/details/122084609https://blog.csdn.net/rzleilei/article/details/122084609

2.本篇主要考察的是各种数据类型的转换,要完成的需求如下:

在java中传入一个对象,JNI中修改这个对象的属性值,然后返回到安卓中展示该对象的属性值。

一。流程步骤

安卓中调用jni主要包含以下几个步骤:

1.在java中声明引用。

2.在jni中创建对应的h文件和cpp文件。

3.在CMakeLists中进行声明,声明之后jni中的方法才能被java外部调用。

4.java层中构造各种数据类型,然后传给JNI进行调用。

二。在java中创建声明类

1.JAVA中生命好JNI调用方法。

package com.xt.client.jni;

import com.xt.client.model.JavaModel;

public class CalculationJNITest {

    static {
        System.loadLibrary("Calculation");
    }

    /**
     * JNI修改属性值
     * @param javaModel
     * @return
     */
    public native Object updateObjectValue(JavaModel javaModel);

}

2.创建JAVA类,这个类传入到JNI中,然后在JNI中修改属性值。

public class JavaModel {
    public String name;
    public int age;
    public String moblie;

    public void printJavaLog() {
        Log.i("lxltest", "java log");
    }

    public String getMoblie() {
        return moblie;
    }

    public void setMoblie(String moblie) {
        this.moblie = moblie;
    }

}

三。在jni中创建h和cpp文件

1,2流程和上一篇文章中流程是一样的,就不详细介绍了。

1.创建com_xt_client_jni_CalculationJNITest.h文件

2.创建CalculationNative.cpp文件

3.h文件中进行方法的声明

h中声明方法:

JNIEXPORT jobject JNICALL Java_com_xt_client_jni_CalculationJNITest_updateObjectValue
        (JNIEnv *, jobject, jobject);

4.CalculationNative.cpp中创建具体实现方法:

方法如下:

JNICALL jobject
Java_com_xt_client_jni_CalculationJNITest_updateObjectValue(JNIEnv *env, jobject instance,
                                                            jobject model) {
    //1
    jclass cls = env->GetObjectClass(model);
    //2
    jfieldID fid = env->GetFieldID(cls, "name", "Ljava/lang/String;");
    //3.
    jstring jstr = static_cast<jstring>(env->GetObjectField(model, fid));
    const char *str = env->GetStringUTFChars(jstr, NULL);
    //4
    env->ReleaseStringUTFChars(jstr, str);
    //5
    jstr = env->NewStringUTF("lll");
    //6
    env->SetObjectField(model, fid, jstr);
    //7
    jmethodID id = env->GetMethodID(cls, "printJavaLog", "()V");
    //8
    env->CallVoidMethod(model, id);
    //9
    id = env->GetMethodID(cls, "setMoblie", "(Ljava/lang/String;)V");
    //10
    jstring mobile = env->NewStringUTF("187000000");
    //11
    env->CallVoidMethod(model, id, mobile);
    //12
    id = env->GetMethodID(cls, "getMoblie", "()Ljava/lang/String;");
    //13
    auto moblie2 = (env->CallObjectMethod(model, id));
    LOGI("getMoblie:%s", env->GetStringUTFChars(static_cast<jstring>(moblie2), 0));//
    return model;
}

这里我们主要做了如下几步:

1.通过JNIEnv提供的方法,获取传过来对象的class类。

2.通过JNIEnv提供的方法,获取class中name的属性ID。

3.获取model中name的属性值。

4.释放name的属性值字符串。

5.jstr字符串赋值为lll

6.通过JNIEnv提供的方法,把jstr赋值类model对象的name属性。这里是通过JNI直接修改对象属性值。

7.获取cls类的printJavaLog方法的ID,

8.根据上一步获取的ID,调用printJavaLog方法

9.获取JavaModel方法中的setMoblie方法的方法ID

10.构造jstring类型的字符串moblie

11.调用setMoblie方法,传入上一步构造的字符串。这里就是通过jni调用java的方法进行赋值。

12.获取getMoblie方法的方法ID

13.JNI中调用getMoblie方法获取返回值,然后在JNI中进行打印。

四。CMakeLists中做好声明

和上一篇中都是一样的。

1.创建文件Cmake文件:

src同级目录下,创建CMakeLists.txt文件,内容如下:逻辑和上一篇文章是一样的。

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library(
        Calculation
        SHARED
        src/main/jni/CalculationNative.cpp)

2.CMakeLists中创建log的连接

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library. 指定连接的目标库
        Calculation
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

3.gradle中做好声明

app的build.gradle文件中,在android{}模块下,添加如下声明:

externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
//            version "3.10.2"
        }
    }

五。验证效果

1.java中写好测试以及调用代码

if (position == 2) {
            try {
                var calculationJNITest = CalculationJNITest()
                val javaModel = JavaModel()
                javaModel.age = 10
                javaModel.moblie = "17863333333"
                javaModel.name = "lxl"
                val calculationSum = calculationJNITest.updateObjectValue(javaModel)
                mResult.text = javaModel.moblie
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return
        }

2.这时候我们通过mResult这个textView输出属性值,发现moblie已经从17863333333改成了18700000了。

 

六。项目源码链接:

https://github.com/aa5279aa/android_all_demohttps://github.com/aa5279aa/android_all_demo/blob/master/DemoClient

调用入口类:

android_all_demo/JNIActivity.kt at master · aa5279aa/android_all_demo · GitHub

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

失落夏天

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

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

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

打赏作者

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

抵扣说明:

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

余额充值