Android ndk jni中回调java的方法&字段描述符

一、jobject和jclass
1.如果定义native方法时使用了static关键字,那么生成的头文件里就会传入jclass,代表这个类的引用。
2.如果没有使用static关键字,那么就会传入jobject,代表类的对象的引用。
二、jni回调java

先贴代码
1.java

package com.example.testcallback;

import android.util.Log;

public class TestCallbackManager {
    private final String TAG = "TestCallbackManager";

    static {
        System.loadLibrary("TestCallback");
    }

    public native void start();

    public void myCallback(int a) {
        Log.e(TAG, "Callback: " + a);
    }

}

2.生成的头文件
ps:如果native方法定义成static,这里就不是jobject,而是jclass

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_testcallback_TestCallbackManager */

#ifndef _Included_com_example_testcallback_TestCallbackManager
#define _Included_com_example_testcallback_TestCallbackManager
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_testcallback_TestCallbackManager
 * Method:    start
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_example_testcallback_TestCallbackManager_start
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

3.c文件

#include <jni.h>
#include <android/log.h>
#include "com_example_testcallback_TestCallbackManager.h"

#define TAG "TestCallbackJNI"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)

JNIEXPORT void JNICALL Java_com_example_testcallback_TestCallbackManager_start
        (JNIEnv *env, jobject obj) {
    __android_log_print(ANDROID_LOG_ERROR, "Callback JNI", "begin");

    jclass clazz = (*env)->GetObjectClass(env, obj);
    jmethodID mID = (*env)->GetMethodID(env, clazz, "myCallback", "(I)V");
    (*env)->CallVoidMethod(env, obj, mID, 10);

    __android_log_print(ANDROID_LOG_ERROR, "Callback JNI", "end");
}

4.解释c文件
(1)在同一个类中,定义native方法和要调用的callback方法,为的是可以在当前的对象引用obj中找到当前类的引用,然后找到这个回调方法。
(2)GetObjectClass,通过obj找到当前类。
(3)GetMethodID找到回调方法,参数:env引用,类引用,方法名,字段描述符(这里看第四条)
(4)字段描述符:
  (a)JNI中描述字段使用字段描述符,描述方法同样有方法描述符。一个方法描述符包含参数类型和返回值类型。参数类型出现在前面,并由一对圆括号将它们括起来,参数类型按它们在方法声明中出现的顺序被列出来,并且多个参数类型之间没有分隔符。如果一个方法没有参数,被表示为一对空圆括号。方法的返回值类型紧跟参数类型的右括号后面。
  (b)描述符对应符号:
   Boolean~~~Z
   Byte~~~B
   Char~~~C
   Short~~~S
   Int~~~I
   Long~~~J
   Float~~~F
   Double~~~D
   Void~~~V
   
   objects对象:
   以”L”开头,以”;”结尾,中间是用”/” 隔开的包及类名。比如:Ljava/lang/String;。嵌套类:Ljava/xx/外部类名$内部类名;
  (c)方法描述符中可能会包含类描述符,如方法native private String getLine(String);的描述符为:“(Ljava/lang/String;)Ljava/lang/String;”
  (d)数组类型的描述符以“[”开头,后面跟着数组元素类型的描述符。如,public static void main(String[] args);的描述符是:”([Ljava/lang/String;)V”
  (e)举例:

// 描述符:(IFDZ)V
public void method1(int a,float f,double b,boolean b){
}

// 描述符:(Ljava/lang/String;)I
public int method2(String s){
    return 0;
}

//描述符:()[I
public int[] method3(){
    return null;
}

(5)CallVoidMethod 调用回调方法,并传入相应值。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值