简体   繁体   中英

Android Native Activity - Call Java method

I've been trying for a while to call a java method from c++, I am able to do it successfully with an Activity class but with a NativeActivity, it crashes when calling CallVoidMethod. GetMethodID is able to find it, it returns an address. env & vm objects are valid & are populated from android_main(). Is it possible that it simply won't work with a native activity class?

Cpp: (edited)

void SendNotification() {

    JavaVM* lJavaVM = main_activity->vm;
    JNIEnv* lJNIEnv = main_activity->env;

    JavaVMAttachArgs lJavaVMAttachArgs;
    lJavaVMAttachArgs.version = JNI_VERSION_1_6;
    lJavaVMAttachArgs.name = "NativeThread";
    lJavaVMAttachArgs.group = NULL;

    jint lResult = lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs);
    if (lResult == JNI_ERR)
        return;

    jobject lNativeActivity = main_activity->clazz;
    jclass ClassNativeActivity = lJNIEnv->GetObjectClass(main_activity->clazz);
    jmethodID _method = lJNIEnv->GetMethodID(ClassNativeActivity, "SendNotification", "()V");

    lJNIEnv->CallVoidMethod(lNativeActivity, _method);

    lJavaVM->DetachCurrentThread();
}


Java:

package com.thor.kalen;

import android.app.AlertDialog;
import android.app.NativeActivity;
import android.os.Bundle;

public class MainActivity extends NativeActivity
{
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    } // End of public void onCreate(Bundle savedInstanceState)

    public void SendNotification() {
        new AlertDialog.Builder(this).setTitle("Alert").setMessage("").setNeutralButton("Close", null).show();
    }
}

com.thor.kalen.MainActivity.SendNotification() Java method should be called for a jobject of class com.thor.kalen.MainActivity , not a jclass of this object: it's not a static method:

main_activity->env->CallVoidMethod(main_activity.clazz, _method)

Note the comment in native_activity.h :

 /** * The NativeActivity object handle. * * IMPORTANT NOTE: This member is mis-named. It should really be named * 'activity' instead of 'clazz', since it's a reference to the * NativeActivity instance created by the system for you. * * We unfortunately cannot change this without breaking NDK * source-compatibility. */ jobject clazz; 

Also, you can only show() an AlertDialog from the Main (UI) thread. Your C++ code suggests that you do you from a background thread.

If this code executes on the main thread, then

main_activity->vm->DetachCurrentThread()

should be removed. AttachThread() can be removed, too, but it's a NOP when called on a thread that is already attached.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM