JNI C调 Java 代码报错

detected:发现,发觉,查明
这个是运行时出现报的错,指的是TestAliPayActivity 里面的showDialog传的jobject应该是 Activity而不应该是JnitUtil这个类;
主要原因是native方法在JniUtil中定义。这边需要弹出一个弹窗,Dialog需要的Context是Activity
所以报实例对象不正确;
改正方法: 将native方法定义在Activity中然后用c代码调用。在C中通过反射的原理可以调用Java代码显示弹窗。

JNI DETECTED ERROR IN APPLICATION:
 can't call void test.com.zh.testicbclient.ui.TestAliPayActivity.showDailog(java.lang.String) 
 on instance of test.com.zh.testicbclient.JniUtils.JniUtil

2.以下是用反射C调取Java的方法:达到Java调c,c调java的闭环。

/**
 *  显示Java的对话框
 * @param env
 * @param obj
 * @param str c的字符串
 */
void showJavaDialog(JNIEnv *env, jobject obj, char *cstr) {


    // c调 java 利用反射的原理 jclass      (*FindClass)(JNIEnv*, const char*);
    // 1 加载类的字节码文件 第一个文件时JVM第二个参数是字符串也就是类的全路径
    // 需要注意全路径C代码不能用点表示了,c中用/
    jclass jclzz = (*env)->FindClass(env, "test/com/zh/testicbclient/ui/TestAliPayActivity");
    // 2.查找类的方法

    // jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    // 第一个参数是JVM,第二个参数是字节码,jclass;第三个参数是字符串方法的名称;第四个参数是
    // 第三个参数是方法名字
    // 第四个参数是方法的签名
    /* public void showDailog(java.lang.String);
     descriptor: (Ljava/lang/String;)V
   (Ljava/lang/String;)V

     解析: (Ljava/lang/String;) 参数类型 Java Lang包的 String 类型 ,后面一个是返回值类型 V void
     public void dismissDialog();
     descriptor: ()V
 */
    jmethodID method = (*env)->GetMethodID(env, jclzz, "showDailog", "(Ljava/lang/String;)V");

    // 3.调用方法;  void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
    // 这地方需要注意最后一个参数传的是 jstring  java中的 字符串
    (*env)->CallVoidMethod(env, obj, method, (*env)->NewStringUTF(env, cstr));


}

3.关于C调java中查找类中的方法签名的获取方法:
第三个参数是方法名,第四个参数是方法的签名

   jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);

关于方法的签名获取的方法需要知道 javap命令:
Android Studio 下获取某个类的方法签名步骤:

Project------>app ---------->build----->intermediates(中间者)------>javaC---->debug---->compileDebugJavaWithJavac-->

classes--------->包名类名对应的方法类下执行 javap -s 可以获取到对应方法的方法签名

在Terminal中 :
eg. cd 项目名\app\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes\包名+类名
执行:javap -s 获取类中方法的签名。
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值