安卓NDK开发之快速熟悉JNI参数的回调

前言:在上一节中我们介绍了通过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>
--------完-------

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等待着冬天的风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值