ndk 开发(ndk层调用java层方法)

这篇博客详细介绍了JNI在Android中如何操作Java对象,包括修改对象属性、调用静态方法以及通过接口进行方法回调。示例代码展示了从NDK层面访问和修改Java对象的属性,调用Java静态方法,以及如何通过JNI调用实现了Java接口的方法,传递数据并执行相应操作。
摘要由CSDN通过智能技术生成

1、ndk层修改java层的对象的属性

package com.yuanxuzhen.testnative;

public class UserData {
    public String name;
    public String sex;
    public int age;

    public UserData(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public UserData(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "UserData{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }
}
 public native UserData callNativeUserData(UserData data);
JNIEXPORT jobject JNICALL
Java_com_yuanxuzhen_testnative_MainActivity_callNativeUserData(JNIEnv *env, jobject thiz,
                                                               jobject data) {
    // TODO: implement callNativeUserData()
    jclass  cls = (*env)->GetObjectClass(env, data);
    jfieldID jfieldId = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;");
    jstring jstring1 = ((*env)->GetObjectField(env, data, jfieldId));
    const char* c = (*env)->GetStringUTFChars(env,jstring1, 0);
    LOGE("native name = %s", c );
    (*env)->ReleaseStringUTFChars(env,jstring1, c);

    jstring jstring2 = (*env)->NewStringUTF(env,"yuanping");
    (*env)->SetObjectField(env,data, jfieldId, jstring2);
    return data;
}

2、ndk层访问java层的静态方法

    public static void testStaticJniCallJava(String name){
        Log.e("xxxx", "testJniCallJava name="+name);
    }

 public native void jniCallJava();

    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        jniCallJava();

    }
JNIEXPORT void JNICALL
Java_com_yuanxuzhen_testnative_MainActivity_jniCallJava(JNIEnv *env, jobject thiz) {
    jclass cls = (*env)->GetObjectClass(env, thiz);
    jmethodID  jmethodId = (*env)->GetStaticMethodID(env, cls, "testStaticJniCallJava", "(Ljava/lang/String;)V");
    (*env)->CallStaticVoidMethod(cls, jmethodId, (*env)->NewStringUTF(env,"yuanjingyao"));
}

thiz代表调用的对象

3、ndk层调用对象的方法

public native void callInterface(ITest test);
//extern "C"
JNIEXPORT void JNICALL
Java_com_yuanxuzhen_testnative_MainActivity_callInterface(JNIEnv *env, jobject thiz, jobject test) {
    LOGE("callInterface 1111111");

    jclass cls = (*env)->GetObjectClass(env, test);
    jmethodID methodId = (*env)->GetMethodID(env,cls, "printUserData",
                                          "(Lcom/yuanxuzhen/testnative/UserData;)V");
    jstring name = (*env)->NewStringUTF(env,getYuanxzh());
    jstring sex = (*env)->NewStringUTF(env, "female");
    jint age = 2;
    jclass userDataClass =  (*env)->FindClass(env,"com/yuanxuzhen/testnative/UserData");
    jmethodID useGenId = (*env)->GetMethodID(env,userDataClass, "<init>",
                                          "(Ljava/lang/String;Ljava/lang/String;I)V");

    jobject useObject = (*env)->NewObject(env,userDataClass, useGenId, name, sex, age);

    (*env)->CallVoidMethod(env,test, methodId, useObject);

    LOGE("callInterface 222222");

}

4、ndk层创建java层对象

    jclass userDataClass =  (*env)->FindClass(env,"com/yuanxuzhen/testnative/UserData");
    jmethodID useGenId = (*env)->GetMethodID(env,userDataClass, "<init>",
                                          "(Ljava/lang/String;Ljava/lang/String;I)V");

    jobject useObject = (*env)->NewObject(env,userDataClass, useGenId, name, sex, age);

    (*env)->CallVoidMethod(env,test, methodId, useObject);

5 ndk 层方法调用java接口

public interface ITest {
     void printUserData(UserData data);
}
 public native void callInterface(ITest test);
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        binding.sampleText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                callInterface(new ITest() {
                    @Override
                    public void printUserData(UserData data) {
                        Log.e("xxxx", "printUserData data = " + data);
                    }
                });
            }
        });

    }
Java_com_yuanxuzhen_testnative_MainActivity_callInterface(JNIEnv *env, jobject thiz, jobject test) {
    LOGE("callInterface 1111111");

    jclass cls = (*env)->GetObjectClass(env, test);
    jmethodID methodId = (*env)->GetMethodID(env,cls, "printUserData",
                                          "(Lcom/yuanxuzhen/testnative/UserData;)V");
    jstring name = (*env)->NewStringUTF(env,getYuanxzh());
    jstring sex = (*env)->NewStringUTF(env, "female");
    jint age = 2;
    jclass userDataClass =  (*env)->FindClass(env,"com/yuanxuzhen/testnative/UserData");
    jmethodID useGenId = (*env)->GetMethodID(env,userDataClass, "<init>",
                                          "(Ljava/lang/String;Ljava/lang/String;I)V");

    jobject useObject = (*env)->NewObject(env,userDataClass, useGenId, name, sex, age);

    (*env)->CallVoidMethod(env,test, methodId, useObject);

    LOGE("callInterface 222222");

}

从上面可以知道java层的接口到了ndk层就成了对象

6、ndk层调用java的构造函数

jclass userDataClass =  (*env)->FindClass(env,"com/yuanxuzhen/testnative/UserData");
    jmethodID useGenId = (*env)->GetMethodID(env,userDataClass, "<init>",
                                          "(Ljava/lang/String;Ljava/lang/String;I)V");

    jobject useObject = (*env)->NewObject(env,userDataClass, useGenId, name, sex, age);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值