JNI调用Java方法总结

1、首先了解一下native方法的方法签名,方法签名主要是描述了方法的参数和返回值,为了防止方法的重载而导致的调用混乱。

Java 类型 类型签名
void V
boolean Z
byte B
char C
short S
int I
long L
float F
double D
类 L全限定名;,比如String, 其签名为Ljava/lang/String;
数组 [类型签名, 比如 [B

在app\build\intermediates\classes\debug的路径下,运行javap -s yys.com.myjnidemo.JniDataUtil,就会输出如下的方法签名描述:

public class yys.com.myjnidemo.JniDataUtil {
  public yys.com.myjnidemo.JniDataUtil();
    descriptor: ()V

  public static native java.lang.String getStringFromJni();
    descriptor: ()Ljava/lang/String;    //括号里面为空,表示参数为空;返回值是String类型

  public static native java.lang.String getStringFromJni(int);
    descriptor: (I)Ljava/lang/String;  //参数是int;返回是String类型

  public native void doSomeThings();
    descriptor: ()V   //参数为空;返回都是void类型

  public native void doSomeThings(java.lang.String);
    descriptor: (Ljava/lang/String;)V

如果修改了类里面的方法,需要重新build一下就好了。

2、jni调用java静态方法

 JNIEXPORT void JNICALL Java_yys_com_myjnidemo_JniDataUtil_doSomeThings__
    (JNIEnv * env, jobject obj){
        /**
        *找到要调用的类
        */
        jclass cls_util = env->FindClass("yys/com/myjnidemo/JniDataUtil");   //注意,这里的使用的斜杠而不是点
        if(cls_util == NULL){
            return;
        }

        /**
        *获取静态方法操作的对象 ,参数分别是 jclass,方法名称,方法签名
        */
        jmethodID mtd_static_method = env->GetStaticMethodID(cls_util,"callStaticHandle","(Ljava/lang/String;)V");
        if(mtd_static_method == NULL){
            return;
        }

        jstring data = env->NewStringUTF("call static method");
        if(data == NULL){
            return;
        }

        /**
        *调用方法,参数是 jclass,jmethodID,传递的参数
        */
        env->CallStaticVoidMethod(cls_util,mtd_static_method,data);

        //删除引用
        env->DeleteLocalRef(cls_util);
        env->DeleteLocalRef(mtd_static_method);
        env->DeleteLocalRef(data);
    }

3、jni调用java实例方法

 /**
            *找到要调用的类
            */
            jclass cls_util = env->FindClass("yys/com/myjnidemo/JniDataUtil");   //注意,这里的使用的斜杠而不是点
            if(cls_util == NULL){
                return;
            }

            /**
            *获取实例方法操作的对象 ,参数分别是 jclass,方法名称,方法签名
            */
             jmethodID mtd_method = env->GetMethodID(cls_util,"callInstanceHandle","([I)V");
               if(mtd_method == NULL){
                    return;
               }

             /**
             *获取构造方法
             */
             jmethodID mtd_struct = env->GetMethodID(cls_util,"<init>","()V");
               if(mtd_struct == NULL){
                    return;
               }

             /**
              *获取实例对象
              */
              jobject utilinstance = env->NewObject(cls_util,mtd_struct,NULL);

              jstring data = env->NewStringUTF("call instance method");
                if(data == NULL){
                     return;
               }

               /**
               *调用实例方法
               */
               env->CallVoidMethod(utilinstance,mtd_method,data);

                //删除引用
                env->DeleteLocalRef(cls_util);
                env->DeleteLocalRef(mtd_method);
                env->DeleteLocalRef(mtd_struct);
                env->DeleteLocalRef(utilinstance);
                env->DeleteLocalRef(data);

可以看出,调用实例方法之前,首先需要获取类的构造方法,然后创建实例对象,用实例对象来作为参数调用实例方法。

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值