在上一篇的基础上,添加在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==){
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) < ){
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 -;
}
assert(env != NULL);
//指定类的路径,通过FindClass 方法来找到对应的类
const char* className = "com/example/scarecrow/dynamicregisterjni/Demo";
//开始注册函数 registerNatives -》registerNativeMethods -》env->RegisterNatives
if(!registerNativeMethods(env,className,getMethods, )){
return -;
}
//返回jni 的版本
return JNI_VERSION_1_6;
}

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

Android jni中回调java的方法的更多相关文章

  1. Android C代码回调java方法

    本文将讲述下列三种C代码回调java方法 1.c代码回调java空方法 2.c代码回调java int类型参数方法 3.c代码回调javaString类型参数方法 方法都差不多,先看c代码回调java ...

  2. ZT ANDROID jni 中的事件回调机制JNIenv的使用 2012-09-10 12:53:01

    ANDROID jni 中的事件回调机制JNIenv的使用 2012-09-10 12:53:01 分类: 嵌入式 android framework 里java调用native,使用JNI机制,ja ...

  3. Java Native Interfce三在JNI中使用Java类的普通方法与变量

    本文是<The Java Native Interface Programmer's Guide and Specification>读书笔记 前面我们学习了如何在JNI中通过参数来使用J ...

  4. Jni层回调java代码【转】

    本文转载自:http://www.linuxidc.com/Linux/2014-03/97562.htm JNI是Java Native Interface的缩写,是Java平台的重要特性,使得Ja ...

  5. Android JNI学习(三)——Java与Native相互调用

    本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...

  6. [原创]Android系统中常用JAVA类源码浅析之HashMap

    由于是浅析,所以我只分析常用的接口,注意是Android系统中的JAVA类,可能和JDK的源码有区别. 首先从构造函数开始, /** * Min capacity (other than zero) ...

  7. 快速掌握 Android Studio 中 Gradle 的使用方法

    快速掌握 Android Studio 中 Gradle 的使用方法 Gradle是可以用于Android开发的新一代的 Build System, 也是 Android Studio默认的build ...

  8. 003android初级篇之【转】Android开发中颜色的定义方法

    正好用到颜色的定义,但脑子里没有记住具体,转载一篇加强印象 1.使用Color类的常量,如: int color = Color.BLUE; // 创建一个蓝色 是使用Android提供的颜色 int ...

  9. 在android开发中使用multdex的方法-IT蓝豹为你整理

    Android系统在安装应用时,往往需要优化Dex,而由于处理工具DexOpt对id数目的限制,导致其处理的数目不能超过65536个,因此在Android开发中,需要使用到MultiDex来解决这个问 ...

随机推荐

  1. net基础运算符

    1.Convert类型转换 总结:      类型如果相兼容的两个变量,可以使用自动类型转换或者强制类型转换.   但是,如果两个类型的变量不兼容,比如string与int或者string 与doub ...

  2. 『Python CoolBook:Collections』数据结构和算法_容器型value字典&顺序字典

    一.collections.defaultdict:多值映射字典 defaultdict省去了初始化容器的过程,会默认value对象为指定类型的容器 指定list时可以使用.append, from ...

  3. hdu5421Victor and String 两端加点的pam

    题意:要求维护两端加点的字符串,以及查询本质回文串个数和所有回文串个数 题解:pam,两端加点过程详见ioi2017国家集训队论文,维护一个最长回文前缀和最长回文后缀即可,fail不用两个,能前后共用 ...

  4. Python 多进程进程池Queue进程通信

    from multiprocessing import Pool,Manager import time def hanshu(queue,a): n = 1 while n<50: # pri ...

  5. python scrapy同时执行spiders多个爬虫

    假设spiders文件夹下多个文件: name.py     name = 'name' name1.py    name = 'name1' name2.py    name = 'name2' . ...

  6. IO模型--阻塞IO,非阻塞IO,IO多路复用,异步IO

    IO模型介绍: * blocking IO 阻塞IO * nonblocking IO 非阻塞IO * IO multiplexing IO多路复用 * signal driven IO 信号驱动IO ...

  7. sql查询练习

    #建学生信息表student create table student ( sno varchar(20) not null primary key, sname varchar(20) not nu ...

  8. Mac上实现ProxyChains-NG终端代理

    附上官方网站,可以自行查看:https://github.com/rofl0r/proxychains-ng 操作步骤如下: 1.在终端上用brew 安装ProxyChains-NG brew ins ...

  9. VirtualBox导致Vmware的虚拟机桥接模式网络不通

    VMware内的虚拟机,设置为桥接后,无法连接外网.物理主机IP地址:192.168.0.60,虚拟机IP地址:192.168.0.61,网关地址:192.168.0.1虚拟机网络采用桥接模式: 从物 ...

  10. es6新增 set

    Set 基本用法 ES6提供了新的数据结构Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set本身是一个构造函数,用来生成Set数据结构. var s = new Set(); [2, ...