C++ 全局调用Java方法

作者: ZebraWei | 来源:发表于2019-11-09 18:10 被阅读0次

版权声明:本文为卫伟学习总结文章,转载请注明出处!
一、C++主线程调用Java方法

    1. 根据jobject获取jclass(静态方法就不用这一步了)如: jclass clz = env->GetObjectClass(jobj);
  • 2.获取jmethodid 如:jmethodid jmid = env->GetMethodID(clz,"onError","(ILjava/lang/String;)V");
  • 3.调用方法如: jenv->CallVoidMethod(jobj,jmid,code,jmsg)

签名方法参数类型对应表

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

通过命令获取native方法签名
在native所在类的class文件目录下,执行命令:
javap -s ***.class


二、C++子线程调用Java方法
由于JniEnv是线程相关的,所以子线程中不能使用创建线程的JniEnv;而JVM是进程相关的,所以可以通过JVM来获取当前线程的JniEnv,然后就可以调用Java的方法了。
  • 1.获取JVM对象: JNI_OnLoad(JavaVM* vm, void *reserved)
    1. 通过JVM获取JniEnv:JNIEnv *env = jvm->AttachCurrentThread(&env,0);
      jvm->DetachCurrentThread();

C++全局调用Java方法Demo

//
// Created by weiwei on 2019/11/9.
//
#include "jni.h"

#ifndef MYMUSIC_JAVALISTENER_H
#define MYMUSIC_JAVALISTENER_H


class JavaListener {

public:
JavaVM *jvm;
_JNIEnv *jenv;
jobject jobj;
jmethodID  jmid;

public:
JavaListener(JavaVM *vm, _JNIEnv *env, jobject obj);
~JavaListener();

/**
 * 1:主线程
 * 2:子线程
 * @param type
 * @param code
 * @param msg
 */
void onError(int type, int code, const char *msg);

};


#endif //MYMUSIC_JAVALISTENER_H

JavaListener.cpp文件

//
// Created by weiwei on 2019/11/9.
//
#include "JavaListener.h"

JavaListener::JavaListener(JavaVM *vm, _JNIEnv *env, jobject obj) {

   jvm = vm;
   jobj = obj;
   jenv = env;
   jclass cls = env->GetObjectClass(jobj);

   if(!cls) {
      return;
   }

   jmid = env->GetMethodID(cls,"onError","(ILjava/lang/String;)V");

   if(!jmid)
     return;

}

void JavaListener::onError(int type, int code, const char *msg) {

   if(type == 0)
   {
  JNIEnv *env;
  jvm->AttachCurrentThread(&env, 0);
  jstring jmsg = env->NewStringUTF(msg);
  env->CallVoidMethod(jobj, jmid, code, jmsg);
  env->DeleteLocalRef(jmsg);

  jvm->DetachCurrentThread();
  }
  else if(type == 1)
 {
  jstring jmsg = jenv->NewStringUTF(msg);
  jenv->CallVoidMethod(jobj, jmid, code, jmsg);
  jenv->DeleteLocalRef(jmsg);
 }
} 

JNI实现代码

#include <jni.h>
#include <string>
#include <android/log.h>
#include "pthread.h"
#include "AndroidLog.h"

extern "C"
{
    #include <libavformat/avformat.h>
}

#include "queue"
#include "unistd.h"

pthread_t produc;
pthread_t custom;
pthread_mutex_t mutex;
pthread_cond_t cond;

#include "JavaListener.h"

JavaVM *jvm;
JavaListener *javaListener;

pthread_t childThread;

void *childCallback(void *data) {
   JavaListener *javaListener1 = (JavaListener *) data;

   javaListener1->onError(0,101,"c++ call java meid from child thread! haha");
   pthread_exit(&childThread);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_day1_jado_mymusic_ThreadDemo_callbackFromC(JNIEnv *env, jobject instance) {
   javaListener = new JavaListener(jvm,env,env->NewGlobalRef(instance)); //得到全局的 instance
    //javaListener->onError(1,100,"c++ call java meid from main thread!");
   pthread_create(&childThread, NULL, childCallback, javaListener);
}

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void* reserved)
{
   JNIEnv *env;
   jvm = vm;
   if(vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK)
   {
    return -1;
   }
   return JNI_VERSION_1_6;
}

相关文章

  • C++子线程调用Java方法

    1. C++ 全局调用Java方法 之前讨论过,如何C++主线程中调用 Java 函数C++主线程调用Java方法...

  • C++主线程调用Java方法

    1. C++ 全局调用Java方法 1.1 C++主线程调用Java方法 在 Android C++多线程-创建子...

  • C++ 全局调用Java方法

    版权声明:本文为卫伟学习总结文章,转载请注明出处!一、C++主线程调用Java方法 根据jobject获取jcla...

  • C++全局调用Java方法

    C++主线程调用Java方法 主要步骤 1、根据jobject获取jclass(静态方法就不用这一步了),如: 2...

  • JNI--c/c++调用Java方法

    上次说到c/c++调用Java的变量,同样的c/c++也可以调用Java的方法 1.c/c++native方法调用...

  • Android 中 C++ 调用 Java, 以及 Java 调

    C++ 调用 Java的原理本质 通过C++中jniEnv的几个关键API实现在C++ 中调用 Java的方法: ...

  • JNI之路径初探---2

    上一篇博客写的是Java调用C、C++的例子,本篇就演示一下C、C++怎么调用Java的属性和方法。

  • JNI基本操作

    JNI(Java Native Interface) Java调用C/C++,C/C++调用Java的一套API ...

  • JNI开发极简教程

    JNI(Java Native Interface) Java调用C/C++,C/C++调用Java的一套API ...

  • C++子线程中调用java方法

    我们通常都是在C++主线程中调用java方法,很简单,但是在子线程中调用java方法却不能采用在主线程中调用的方式...

网友评论

    本文标题:C++ 全局调用Java方法

    本文链接:https://www.haomeiwen.com/subject/bclnbctx.html