java - 如何从 C++ 代码 (android) 调用非静态 Java 方法?

标签 java android c++ java-native-interface

请帮助从 C++ 调用 java void 方法(非静态),它是简单的 sdl2 android 项目。我尝试了很多次,但无法使其正常工作:-(。CallVoidMethod 总是崩溃。

C++代码:

JNIEnv* Android_JNI_GetEnv(void) {
    JNIEnv *env;
    int status = mJavaVM->AttachCurrentThread(&env, NULL);
    if(status < 0) {
        LOGE("failed to attach current thread");
        return 0;
    }

    return env;
}

int Android_JNI_SetupThread(void) {

    JNIEnv *env = Android_JNI_GetEnv();
    pthread_setspecific(mThreadKey, (void*) env);
    return 1;
}   

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    JNIEnv *env;
    mJavaVM = vm;
    LOGI("JNI_OnLoad called");
    if (mJavaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        LOGE("Failed to get the environment using GetEnv()");
        return -1;
    }
        Android_JNI_SetupThread();


    return JNI_VERSION_1_4;
}


void B_Init(JNIEnv* mEnv, jclass cls, jobject obj)
{
    Android_JNI_SetupThread();

    mActivityClass = (jclass)mEnv->NewGlobalRef(cls);

}


extern "C" void Java_org_libsdl_app_SDLActivity_nativeInitB(JNIEnv* env, jclass cls, jobject obj)
{
    /* This interface could expand with ABI negotiation, calbacks, etc. */
    B_Init(env, cls, obj);

}

    void Java_org_libsdl_app_SDLActivity_nativeDemoInit()
    {

    JNIEnv* env = Android_JNI_GetEnv();

    jclass cls;

    jmethodID mid;

    cls =  env->FindClass("org/libsdl/app/SDLActivity");

    mid = env->GetMethodID(cls, "displayInterstitial2", "()V");

    **env->CallVoidMethod(cls, mid2);**

    } 
}

Java 代码(org/libsdl/app/SDLActivity):

/**
    SDL Activity
**/
public class SDLActivity extends Activity {


public void displayInterstitial2() {

            some code;

    }

}

接下来我正在尝试简化代码

C++代码:

JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_nativeinitB(JNIEnv* env, jobject obj)
{
    jclass clz =  env->GetObjectClass(obj);  // instead of FindClass
    jmethodID mid = env->GetMethodID(clz, "displayInterstitial2", "()V");
   // if(!mid) return;  // method does not exist, should write some logs
   env->CallVoidMethod(obj, mid); 
}

并得到错误: 没有原生 Lorg/libsdl/app/SDLActivity;.nativeInitB:()V

的实现

最佳答案

如果你从你的 Activity 中调用本地方法,你可以尝试这种方式:

JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_nativeDemoInit(JNIEnv* env, jobject obj){
   jclass cls = (*env)->GetObjectClass(env,obj);  // instead of FindClass
   jmethodID mid = (*env)->GetMethodID(env, cls, "displayInterstitial2", "()V");
   if(!mid) return;  // method does not exist, should write some logs
   (*env)->CallVoidMethod(env, obj, mid);
}

在 Activity 类中:

 public void displayInterstitial2(){
    Log.d("call displayInterstitial2");
 }

 public native void nativeDemoInit();

引用自thisthis

关于java - 如何从 C++ 代码 (android) 调用非静态 Java 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24864166/

相关文章:

c++ - 指向字符数组 C++ 的指针的问题

c++ - 双C++的算术错误

c++ - C++ 中的字符指针

java - 安卓RTP。不兼容类型 : Object cannot be converted.

java - 如何将 Guardian API 添加到依赖项

android - ListView Adapter - 何时收集附加到 View 的监听器?

javascript - Appcelerator Titanium 中适用于 Android 平台的 Ti.Barcode 模块? (扫码机)

Java Stream sum()短路

java - 带有十进制坐标和多个文本的 System.out.printf

android - 如何设置微小的通知图标徽章