1.创建xxx.jni包并在该包下实现一些Java的方法,和要调用的本地方法

2.实现MainActivity中的按钮点击事件—即点击按钮调用本地的方法

3.在C文件中的方法中回调Java的方法

  3.1:通过env获取字节码对象—>jclass   (*FindClass)(JNIEnv*, const char*)

    第二个参数为要回调Java方法所在类的全路径如:jclass claz = (*env)->FindClass(env, "com/rocky/jniccallbackdemo/jni/JNI");

  3.2:通过字节码对象获取方法ID—>jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);

    第二个参数是由3.1获取的字节码对象,第三个对象是要回调的Java方法名,第四个参数该Java方法签名,因为Java中有重载,需要此参数确定具体是哪个方法如:jmethodID methodId = (*env)->GetMethodID(env, claz, "helloFromJava", "()V")

    注:对应方法签名,需要到工程目录下的bin/classes目录下执行:javap -s com.rocky.jniccallbackdemo.jni.JNI(该方法所在类的全类名)

  3.3:通过字节码对象创建Java对象—>jobject (*AllocObject)(JNIEnv*, jclass);
    如:jobject obj = (*env)->AllocObject(env, claz);

注:如果本地方法和要回调的Java方法在同一个类中,则第二参数就是本地方法传过来的第二个参数,即第三步可以可以省略。

  3.4:通过Java对象回调Java方法

  调用Java的无返回值方法:void  (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...),如: (*env)->CallVoidMethod(env, clazz, methodId);

DEMO:

JNI.java

public class JNI
{
static {
System.loadLibrary("callback");
}
private Context mContext = null;
public JNI(Context context)
{
this.mContext = context;
}
public void helloFromJava()
{
System.out.println("Hello From Java");
}
public void printString(String str)
{
System.out.println(str);
}
public void showToast(String str)
{
Toast.makeText(mContext, str, Toast.LENGTH_SHORT).show();
}
public native void callbackVoidMethod();
public native void callbackStringMethod();
public native void callbackIntMethod();
public native void callbackShowToastMethod();
}

MainActivity.java

public class MainActivity extends Activity implements OnClickListener
{
Context mContext = null;
Button bt_callback_void = null;
Button bt_callback_string = null;
Button bt_callback_int = null;
Button bt_callback_toast = null;
JNI jni = null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
jni = new JNI(mContext);
bt_callback_void = (Button) findViewById(R.id.bt_callback_void);
bt_callback_void.setOnClickListener(this);
bt_callback_int = (Button) findViewById(R.id.bt_callback_int);
bt_callback_int.setOnClickListener(this);
bt_callback_string = (Button) findViewById(R.id.bt_callback_string);
bt_callback_string.setOnClickListener(this);
bt_callback_toast = (Button) findViewById(R.id.bt_callback_toast);
bt_callback_toast.setOnClickListener(this);
}
public int add(int x, int y)
{
return x + y;
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.bt_callback_void:
jni.callbackVoidMethod();
break;
case R.id.bt_callback_int:
jni.callbackIntMethod();
break;
case R.id.bt_callback_string:
jni.callbackStringMethod();
break;
case R.id.bt_callback_toast:
jni.callbackShowToastMethod();
break; default:
break;
}
}
}

callback.c

#include <jni.h>
#include <android/log.h>
#define LOG_TAG "rocky"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) JNIEXPORT void JNICALL Java_com_rocky_jniccallbackdemo_jni_JNI_callbackVoidMethod
(JNIEnv *env, jobject clazz)
{
//1.获取字节码对象 jclass (*FindClass)(JNIEnv*, const char*);
jclass claz = (*env)->FindClass(env, "com/rocky/jniccallbackdemo/jni/JNI");
//2.通过字节码对象获取方法ID jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID methodId = (*env)->GetMethodID(env, claz, "helloFromJava", "()V");
//3.通过字节码对象创建Java对象(此处因为本地方法和回调方法在同一个类中,可以省略)
//4.通过Java对象回调Java方法 void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
(*env)->CallVoidMethod(env, clazz, methodId);
}
/*
* Class: com_rocky_jniccallbackdemo_jni_JNI
* Method: callbackIntMethod
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_rocky_jniccallbackdemo_jni_JNI_callbackIntMethod
(JNIEnv *env, jobject clazz)
{
jclass claz = (*env)->FindClass(env, "com/rocky/jniccallbackdemo/MainActivity");
jmethodID methodId = (*env)->GetMethodID(env, claz, "add", "(II)I");
//3.通过字节码对象创建Java对象(此处为MainActivity对象) jobject (*AllocObject)(JNIEnv*, jclass);
// jobject obj = (*env)->AllocObject(env, claz);
//4.通过Java对象回调Java方法 void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
jobject obj = (*env)->AllocObject(env, claz);
jint res = (*env)->CallIntMethod(env, obj, methodId, , );
LOGI("res = %d\n", res);
}
JNIEXPORT void JNICALL Java_com_rocky_jniccallbackdemo_jni_JNI_callbackStringMethod
(JNIEnv *env, jobject clazz)
{
jclass claz = (*env)->FindClass(env, "com/rocky/jniccallbackdemo/jni/JNI");
jmethodID methodId = (*env)->GetMethodID(env, claz, "printString", "(Ljava/lang/String;)V");
jstring result = (*env)->NewStringUTF(env, "cccccccccccccc");
(*env)->CallVoidMethod(env, clazz, methodId, result);
}
JNIEXPORT void JNICALL Java_com_rocky_jniccallbackdemo_jni_JNI_callbackShowToastMethod
(JNIEnv *env, jobject clazz)
{
jclass claz = (*env)->FindClass(env, "com/rocky/jniccallbackdemo/jni/JNI");
jmethodID methodId = (*env)->GetMethodID(env, claz, "showToast", "(Ljava/lang/String;)V");
jstring result = (*env)->NewStringUTF(env, "rocky--------rocky");
(*env)->CallVoidMethod(env, clazz, methodId, result);
}

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := callback
LOCAL_SRC_FILES := callback.c LOCAL_LDLIBS += -llog include $(BUILD_SHARED_LIBRARY)

JNI系列——C文件中的方法调用Java中方法的更多相关文章

  1. 不用static,巧用对象.方法调用java中的函数

    先生成一个对象,用"对象.方法()"的方式调用. java中的main方法是静态的,用于程序的入口,在静态方法中无法调用非静态方法,只能调用静态方法.想调用静态方法的话就要先生成该 ...

  2. C通过JNI反向调用JAVA程序方法

    JNI反向调用JAVA程序 引述:上文讲过java线程---OS线程的关系,然后C怎样反向调用JAVA程序方法是我们这篇讲的重点 1.ThreadTest中添加run()方法 2.编译ThreadTe ...

  3. 在ASP.Net环境中,当用户点击报表中的超链接时如何调用Java Script方法?

    问题描述:在ASP.Net环境中,当用户点击报表中的超链接时如何调用Java Script方法? 问题解答: 你可以在TextObject.Hyperlink对象中编写js代码(javascript: ...

  4. 第7.22节 Python中使用super调用父类的方法

    第7.22节 Python中使用super调用父类的方法 前面章节很多地方都引入了super方法,这个方法就是访问超类这个类对象的.由于super方法的特殊性,本节单独谈一谈super方法. 一.su ...

  5. vue中methods一个方法调用另外一个方法

    转自http://blog.csdn.net/zhangjing1019/article/details/77942923 vue在同一个组件内: methods中的一个方法调用methods中的另外 ...

  6. 为什么static方法中不可以调用非static方法

    Java是面向对象的语言,所有的变量,方法都是针对对象而言的.一般来说,要调用一个方法,你需要new 这个方法的对象. 什么时候用static? 如果你想要: 对于一个类的所有对象共享一个变量或者是方 ...

  7. vue methods 方法中 方法 调用 另一个方法。

    vue在同一个组件内: methods中的一个方法调用methods中的另外一个方法. 可以在调用的时候 this.$options.methods.test(); this.$options.met ...

  8. PySpark 的背后原理--在Driver端,通过Py4j实现在Python中调用Java的方法.pyspark.executor 端一个Executor上同时运行多少个Task,就会有多少个对应的pyspark.worker进程。

    PySpark 的背后原理 Spark主要是由Scala语言开发,为了方便和其他系统集成而不引入scala相关依赖,部分实现使用Java语言开发,例如External Shuffle Service等 ...

  9. JNI NDK (AndroidStudio+CMake )实现C C++调用Java代码流程

    JNI/NDK Java调用C/C++前言  通过第三篇文章讲解在实际的开发过程中Java层调用C/C++层的处理流程.其实我们在很大的业务里也需要C/C+ +层去调用Java层,这两层之间的相互调用 ...

随机推荐

  1. MMORGP大型游戏设计与开发(客户端架构 part1 of vgui)

    作为客户端的重要装饰,UI扮演着极为重要的角色,是客户端中核心的组成.vgui(微GUI)中,提供了核心的接口封装,实现了客户端中常见的界面操作,并结合lua脚本,使得控制界面更加的方便. 构架 总结 ...

  2. Hibernate之组件映射

    1:为什么要使用组件映射 答:建立关系数据模型的一个重要原则是在不会导致数据冗余的前提下,尽可能减少数据库表的数目及表之间的外键参照关系.以员工信息为例,员工信息中有员工的家庭地址信息,如果把地址信息 ...

  3. ApplicationWindow

    本文介绍了一个使用ApplicationWindow 和Action 实现的一个文本编辑器.界面美观,基本功能齐全.代码齐全. 首先看 MainWindow.java. //MainWindow.ja ...

  4. JS获取当前页面的URL信息

    设置或获取对象指定的文件名或路径. <script> alert(window.location.pathname) </script> 设置或获取整个 URL 为字符串. & ...

  5. [Cache] C#操作缓存--CacheHelper缓存帮助类 [复制链接]

    using System;using System.Web;using System.Collections; namespace DotNet.Utilities{ public class Cac ...

  6. K910 升级Android 4.4.2可用的Google Service Framework

    把手机换成了K910, 看上的是骁龙800的cpu和电子罗盘... 比V987是升级一大截了. 花了一个晚上加半个上午的时间终于搞定了GoogleServiceFramework, 试了大概四五个网上 ...

  7. Delphi项目的构成

    Hello.cfg 項目配置文件 Hello.dof 項目選項文件 Hello.dpr 項目文件 Hello.exe 應用程序 Hello.res 資源文件 HelloWorld.dcu 窗口編譯文件 ...

  8. 【C#】【Thread】Semaphore/SemaphoreSlim信号量

    System.Threading.Semaphore 类表示一个命名(系统范围)信号量或本地信号量. 它是一个对 Win32 信号量对象的精简包装. Win32 信号量是计数信号量,可用于控制对资源池 ...

  9. ASP.NET MVC图片上传前预览

    回老家过春节,大半个月,在家的日子里,吃好睡好,人也长了3.5Kg.没有电脑,没有网络,无需写代码,工作上相关的完全放下......开心与父母妻儿过个年,那样的生活令Insus.NET现在还在留恋.. ...

  10. 用微信小程序做H5游戏尝试

    微信小程序发布后,公司虽然没有拿到第一批内测资格,但作为微信亲密合作伙伴,一定要第一时间去尝试啦.现在微信小程序刚发布还在测试阶段,可以说是1.0版本,所以框架和结构内容都还不多,相关的文档跟微信AP ...