zoukankan      html  css  js  c++  java
  • Android jni中回调java的方法

    在上一篇的基础上,添加在C++代码中回调java方法。

    代码如下:

    Demo.java 中添加callback函数, 打印一条log.

    package com.example.scarecrow.dynamicregisterjni;
    
    import android.util.Log;
    
    public class Demo {
        public static final String TAG = "Demo";
    
        static {
            System.loadLibrary("JniTest");
            Log.d(TAG, "dynamic lib loaded");
        }
    
        public static native String sayHello();
    
        public static void callback(String message) {
            Log.d(TAG, message);
        }
    }

    JniTest.cpp 中添加myCallBack方法,在myDynamicJNI中调用,传个字符串回到JAVA。注意:java端的方法是static的话,一定要用GetStaticMethodID和CallStaticVoidMethod

    //
    // Created by yuany on 6/5/18.
    //
    #include <jni.h>
    #include "android/log.h"
    #include <cassert>
    
    #define LOG_TAG  "C_TAG"
    #define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
    
    //native method
    void myCallBack (JNIEnv *env, jclass jobj)
    {
        LOGD("myCallBack");
        jclass clazz;
    
        //找到声明native方法的类
        clazz = env->FindClass("com/example/scarecrow/dynamicregisterjni/Demo");
        if(clazz == NULL){
            LOGD("Findclass error");
            return;
        }
        LOGD("Findclass succeed");
    
        //寻找class里面的方法
        jmethodID callbackID = env->GetStaticMethodID(clazz, "callback", "(Ljava/lang/String;)V");
        if(callbackID==0){
            LOGD("find callback error");
            return;
        }
        LOGD("find callback ");
    
        jstring result = env->NewStringUTF("this is a callback from C++ codes");
        //invoke callback method
        env->CallStaticVoidMethod(jobj,callbackID, result);
    }
    
    //native method
    jstring myDynamicJNI (JNIEnv *env, jclass jobj)
    {
        LOGD("myDynamicJNI");
        //invoke callback method
        myCallBack(env, jobj);
        return env->NewStringUTF("This is my first dynamic JNI test");
    }
    
    /*需要注册的函数列表,放在JNINativeMethod 类型的数组中,
    以后如果需要增加函数,只需在这里添加就行了
    参数:
    1.java代码中用native关键字声明的函数名字符串
    2.签名(传进来参数类型和返回值类型的说明)
    3.C/C++中对应函数的函数名(地址)
    */
    static JNINativeMethod getMethods[] = {
            {"sayHello","()Ljava/lang/String;",(void*)myDynamicJNI},
    };
    //此函数通过调用JNI中 RegisterNatives 方法来注册我们的函数
    static int registerNativeMethods(JNIEnv* env, const char* className,JNINativeMethod* getMethods,int methodsNum){
        LOGD("registerNativeMethods");
        jclass clazz;
        //找到声明native方法的类
        clazz = env->FindClass(className);
        if(clazz == NULL){
            return JNI_FALSE;
        }
        LOGD("after Findclass");
       //注册函数 参数:java类 所要注册的函数数组 注册函数的个数
        if(env->RegisterNatives(clazz,getMethods,methodsNum) < 0){
            return JNI_FALSE;
        }
        LOGD("after RegisterNatives");
        return JNI_TRUE;
    }
    
    //回调函数 在这里面注册函数
    JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){
    
        LOGD("JNI_OnLoad");
        JNIEnv* env = NULL;
       //判断虚拟机状态是否有问题
        if(vm->GetEnv((void**)&env,JNI_VERSION_1_6)!= JNI_OK){
            return -1;
        }
        assert(env != NULL);
        //指定类的路径,通过FindClass 方法来找到对应的类
        const char* className  = "com/example/scarecrow/dynamicregisterjni/Demo";
        //开始注册函数 registerNatives -》registerNativeMethods -》env->RegisterNatives
        if(!registerNativeMethods(env,className,getMethods, 1)){
            return -1;
        }
        //返回jni 的版本
        return JNI_VERSION_1_6;
    }

     关于JNI更多详细内容可以参考https://blog.csdn.net/rainteen/article/details/43376337#t0

  • 相关阅读:
    linux date使用
    SHELL输出带颜色字体
    vimrc配置
    你所不知道的C++
    temp
    说什么好呢3
    Extjs3 Combo实现百度搜索查询
    Extjs3笔记 fbar
    Extjs combo赋值与刷新的先后顺序
    sql中nvarchar(max)长度测试
  • 原文地址:https://www.cnblogs.com/scarecrow-blog/p/9152319.html
Copyright © 2011-2022 走看看