前言:在上一节中我们介绍了通过java传递参数给JNI,今天我们熟悉一下JNI的回调,java访问jni,然后通过类反射的方式拿到java的方法,来实现回调。
----------分割线------
在jni系列中有讲到:《JNI开发之调用java实力类父类的方法》
---------分割线-----
今天我们就在安卓的NDK开发快速实现一下几个demo:
---------分割线------
开始撸代码:java代码:
MainActivity.java:
package com.fly.demo4;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private JNI jni;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
jni = new JNI(this);
}
public void callbackvoidmethod(View view) {
jni.callbackvoidmethod();
}
public void callbackintmethod(View view) {
Toast.makeText(this, "" + jni.callbackintmethod(), Toast.LENGTH_SHORT).show();
}
public void callbackstringmethod(View view) {
jni.callbackStringmethod();
}
public void callbacktoastmethod(View view) {
jni.callbackShowToast();
}
}
JNI.java:
package com.fly.demo4;
import android.content.Context;
import android.widget.Toast;
/**
* Created by Fly on 2017/7/6.
*/
public class JNI {
static {
System.loadLibrary("native-lib");
}
private Context mContext;
public JNI(Context context) {
mContext = context;
}
public native void callbackvoidmethod();
public native int callbackintmethod();
public native void callbackStringmethod();
public native void callbackShowToast();
//C调用java空方法
public void helloFromJava() {
Toast.makeText(mContext, "hello from java", Toast.LENGTH_SHORT).show();
}
//C调用java中的带两个int参数的方法
public int add(int x, int y) {
return x + y;
}
//C调用java中参数为string的方法
public void printString(String s) {
Toast.makeText(mContext, s, Toast.LENGTH_SHORT).show();
}
public void showToast(String s) {
Toast.makeText(mContext, s, Toast.LENGTH_SHORT).show();
}
}
C代码:
#include <jni.h>
#include <stdlib.h>
#include <stdio.h>
/*
* Class: com_fly_demo4_JNI
* Method: callbackvoidmethod
* Signature: ()V
* 回调空方法
*/
JNIEXPORT void JNICALL Java_com_fly_demo4_JNI_callbackvoidmethod
(JNIEnv *env, jobject clazz) {
//1.获取字节码对象
jclass claz = (*env)->FindClass(env, "com/fly/demo4/JNI");
//2.获取Method对象
jmethodID methodID = (*env)->GetMethodID(env, claz, "helloFromJava", "()V");
//3.通过字节码对象创建一个Object
//4.通过对象调用方法
(*env)->CallVoidMethod(env, clazz, methodID);
}
/*
* Class: com_fly_demo4_JNI
* Method: callbackintmethod
* Signature: ()V
* 回调int方法
*/
JNIEXPORT jint JNICALL Java_com_fly_demo4_JNI_callbackintmethod
(JNIEnv *env, jobject clazz) {
jclass claz = (*env)->FindClass(env, "com/fly/demo4/JNI");
jmethodID methodID = (*env)->GetMethodID(env, claz, "add", "(II)I");
int result = (*env)->CallIntMethod(env, clazz, methodID, 10, 20);
return result;
}
/*
* Class: com_fly_demo4_JNI
* Method: callbackStringmethod
* Signature: ()V
* 回调String方法
*/
JNIEXPORT void JNICALL Java_com_fly_demo4_JNI_callbackStringmethod
(JNIEnv *env, jobject clazz) {
jclass claz = (*env)->FindClass(env, "com/fly/demo4/JNI");
jmethodID methodID = (*env)->GetMethodID(env, claz, "printString", "(Ljava/lang/String;)V");
jstring result = (*env)->NewStringUTF(env, "Hello from c");
(*env)->CallVoidMethod(env, clazz, methodID, result);
}
/*
* Class: com_fly_demo4_JNI
* Method: callbackShowToast
* Signature: ()V
* 回调Toast
*/
JNIEXPORT void JNICALL Java_com_fly_demo4_JNI_callbackShowToast
(JNIEnv *env, jobject clazz) {
jclass claz = (*env)->FindClass(env, "com/fly/demo4/JNI");
jmethodID methodid = (*env)->GetMethodID(env, claz, "showToast", "(Ljava/lang/String;)V");
//jobject (*AllocObject)(JNIEnv*, jclass);
//通过字节码对象创建 java对象 在这儿就是创建了mainactivity的对象
//jobject obj =(*env)->AllocObject(env,claz);
jstring result = (*env)->NewStringUTF(env, "hello from c2");
//void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
(*env)->CallVoidMethod(env, clazz, methodid, result);
}
简单的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.fly.demo4.MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="callbackvoidmethod"
android:text="回调空方法" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="callbackintmethod"
android:text="回调int参数方法" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="callbackstringmethod"
android:text="回调string参数方法" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="callbacktoastmethod"
android:text="回调Toast方法" />
</LinearLayout>
--------完-------