JNI调用Java方法

推荐阅读:JNI/NDK入门指南之JNI多线程回调Java方法

gitee代码链接
在这里插入图片描述

1.JNI 调用 Java 无参数无返回值的方法

public native void native_call_java_callBack_method();
public void callBack(){
    Toast.makeText(this, "调用java无参无返回值方法", Toast.LENGTH_LONG).show();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myjnicalljava_MainActivity_native_1call_1java_1callBack_1method(JNIEnv *env,
                                                                                 jobject thiz) {
    // TODO: implement native_call_java_callBack_method()
    LOGI("=========== native_call_java_callBack_method ===========");
    jclass jcl = env->GetObjectClass(thiz);
    jmethodID mid = env->GetMethodID(jcl, "callBack", "()V");
    env->CallVoidMethod(thiz, mid);
}

2.JNI 调用 Java 整型参数无返回值方法

public native void native_call_java_integer_signature_callBack_method();
public void callBack(int num){
    Toast.makeText(this, "调用java有参无返回值方法, 返回整型参数:"+num, Toast.LENGTH_LONG).show();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myjnicalljava_MainActivity_native_1call_1java_1integer_1signature_1callBack_1method(
        JNIEnv *env, jobject thiz) {
    // TODO: implement native_call_java_integer_signature_callBack_method()
    LOGI("=========== native_call_java_integer_signature_callBack_method ===========");
    jclass jcl = env->GetObjectClass(thiz);
    jmethodID mid = env->GetMethodID(jcl, "callBack", "(I)V");
    env->CallVoidMethod(thiz, mid, 145);
}

3.JNI 调用 Java 整型数组参数无返回值方法

public native void native_call_java_integerArray_signature_callBack_method();
public void callBack(int[] arr){
    Toast.makeText(this, "调用java有参无返回值方法, 返回整型数组参数:"+arr[0]+","+arr[1]+","+arr[2], Toast.LENGTH_LONG).show();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myjnicalljava_MainActivity_native_1call_1java_1integerArray_1signature_1callBack_1method(
        JNIEnv *env, jobject thiz) {
    // TODO: implement native_call_java_integerArray_signature_callBack_method()
    LOGI("=========== native_call_java_integer_signature_callBack_method ===========");
    jclass jcl = env->GetObjectClass(thiz);
    jmethodID mid = env->GetMethodID(jcl, "callBack", "([I)V");

    jintArray newArr = env->NewIntArray(3);
    int32_t a[3] = {-145,82,74};
    env->SetIntArrayRegion(newArr, 0, 3, a);
    env->CallVoidMethod(thiz, mid, newArr);
    jint* pnewArr = env->GetIntArrayElements(newArr, 0);
    env->ReleaseIntArrayElements(newArr, pnewArr, 0);
}

4.JNI 调用 Java 字符串型参数无返回值方法

public native void native_call_java_string_signature_callBack_method();
public void callBack(String str){
    Toast.makeText(this, "调用java有参无返回值方法, 返回字符串型参数:"+str, Toast.LENGTH_LONG).show();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myjnicalljava_MainActivity_native_1call_1java_1string_1signature_1callBack_1method(
        JNIEnv *env, jobject thiz) {
    // TODO: implement native_call_java_string_signature_callBack_method()
    LOGI("=========== native_call_java_string_signature_callBack_method ===========");
    jclass jcl = env->GetObjectClass(thiz);
    // 注意括号里面有分号
    jmethodID mid = env->GetMethodID(jcl, "callBack", "(Ljava/lang/String;)V");
    std::string hello = "Hello from JNI";
    env->CallVoidMethod(thiz, mid, env->NewStringUTF(hello.c_str()));
}

5.JNI 在子线程生成整型数组并回调 Java 整型数组参数无返回值方法

public native void native_thread_call_java_integerArray_signature_callBack_method();
public String str = "";
public void callBack(int[] arr, int length){
    Log.e(TAG, "callBack: length = "+length);

    for (int n : arr){
        str+=", ";
        str+=n;
    }
    runOnUiThread(
        new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(), "JNI在子线程生成整型数组并回调Java整型数组参数无返回值方法,JNI生成的整型数组为:"+str, Toast.LENGTH_LONG).show();
            }
        }
    );
}
JavaVM* mVm = NULL;
jobject mObj = NULL;

void* native_thread_exec(void* args){
    LOGI("=========== native_thread_exec ===========");
    JNIEnv *env;
    //从全局的JavaVM中获取到环境变量
    mVm->AttachCurrentThread(&env,NULL);
    jclass clazz = env->GetObjectClass(mObj);
    jmethodID postID = env->GetMethodID(clazz,"callBack","([II)V");
    jintArray newArr = env->NewIntArray(5);
    int32_t a[5] = {415,789,654,-874,-842};
    env->SetIntArrayRegion(newArr, 0, 5, a);
    env->CallVoidMethod(mObj, postID, newArr, 5);
    
    jint* pnewArr = env->GetIntArrayElements(newArr, 0);
    env->ReleaseIntArrayElements(newArr, pnewArr, 0);
    mVm->DetachCurrentThread();
    pthread_exit(NULL);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myjnicalljava_MainActivity_native_1thread_1call_1java_1integerArray_1signature_1callBack_1method(
        JNIEnv *env, jobject thiz) {
    // TODO: implement native_thread_call_java_integerArray_signature_callBack_method()
    LOGI("=========== native_thread_call_java_integerArray_signature_callBack_method ===========");
    if (!mObj) {
        LOGI("=========== !mObj ===========");
        mObj = env->NewGlobalRef(thiz);
    }
    //虽然JNI_OnLoad函数已经保存了JVM,但是那个没用.如果不调用env->GetJavaVM(&mVm); 会在线程中执行到myThreadProcessArray->mVm->AttachCurrentThread报错
    env->GetJavaVM(&mVm);
    pthread_t id;
    //通过pthread库创建线程
    LOGI("=========== create native thread ===========");
    if(pthread_create(&id,NULL, native_thread_exec, NULL)!=0)
    {
        LOGI("=========== native thread create fail ===========");
        return;
    }
}

6.JNI 在子线程生成字节数组并回调 Java 字节数组参数无返回值方法,并写入文件

public native void native_thread_call_java_byteArray_signature_callBack_method();
public String str2 = "";
public void callBack_writeFile(byte[] barr, int length){
    Log.e(TAG, "callBack: length = "+length);
    for (byte b : barr){
        str2+=b;
        str2+=", ";
    }
    Log.e(TAG, "callBack_writeFile:  "+str2 );

    try {
        // 写入文件, 文件的路径在 /data/data/com.example.myjnicalljava/files/ 下面
        FileOutputStream fout = openFileOutput("test.txt", MODE_PRIVATE);
        fout.write(barr);
        fout.close();

        // 把刚才写入的内容,从文件中读出来
        FileInputStream fin = openFileInput("test.txt");
        byte[] readBuffer = new byte[length];
        fin.read(readBuffer);
        for (byte b : readBuffer){
            Log.e(TAG, "callBack_writeFile readBuffer:  "+b );
        }
        fin.close();
        readBuffer = null;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        Log.e(TAG, "callBack_writeFile: IOException" );
        e.printStackTrace();
    }
    runOnUiThread(
        new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(), "JNI在子线程生成字节数组并回调Java字节数组参数无返回值方法,JNI生成的字节数组为:"+str2, Toast.LENGTH_LONG).show();
            }
        }
    );
}
JavaVM* mVm = NULL;
jobject mObj = NULL;
void* native_thread_exec2(void* args){
    LOGI("=========== native_thread_exec ===========");
    JNIEnv *env;
    //从全局的JavaVM中获取到环境变量
    mVm->AttachCurrentThread(&env,NULL);
    jclass clazz = env->GetObjectClass(mObj);
    jmethodID postID = env->GetMethodID(clazz,"callBack_writeFile","([BI)V");

    jbyteArray jbarray = env->NewByteArray(5);//建立jbarray数组
    jbyte* pbarray = env->GetByteArrayElements(jbarray, NULL);
    pbarray[0] = 5;
    pbarray[1] = 9;
    pbarray[2] = 2;
    pbarray[3] = 3;
    pbarray[4] = 4;

    env->SetByteArrayRegion(jbarray, 0, 5, pbarray);            //将Jbyte 转换为jbarray数组
    env->CallVoidMethod(mObj, postID, jbarray, 5);
    env->ReleaseByteArrayElements(jbarray, pbarray, 0);
    mVm->DetachCurrentThread();
    pthread_exit(NULL);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myjnicalljava_MainActivity_native_1thread_1call_1java_1byteArray_1signature_1callBack_1method(
        JNIEnv *env, jobject thiz) {
    // TODO: implement native_thread_call_java_byteArray_signature_callBack_method()
    LOGI("=========== native_thread_call_java_byteArray_signature_callBack_method ===========");
    if (!mObj) {
        LOGI("=========== !mObj ===========");
        mObj = env->NewGlobalRef(thiz);
    }
    //虽然JNI_OnLoad函数已经保存了JVM,但是那个没用.如果不调用env->GetJavaVM(&mVm); 会在线程中执行到myThreadProcessArray->mVm->AttachCurrentThread报错
    env->GetJavaVM(&mVm);
    pthread_t id;
    //通过pthread库创建线程
    LOGI("=========== create native thread ===========");
    if(pthread_create(&id,NULL, native_thread_exec2, NULL)!=0)
    {
        LOGI("=========== native thread create fail ===========");
        return;
    }
}

如果向pthread传递多个参数,可以将这多个参数封装在一个class里面,然后将这个class当作参数传递

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值