Android Native Activity - вызов метода Java

Некоторое время я пытался вызвать java-метод из C++, я могу успешно сделать это с классом Activity, но с NativeActivity он вылетает при вызове CallVoidMethod. GetMethodID может его найти, он возвращает адрес. Объекты env и vm действительны и заполняются из android_main (). Возможно ли, что он просто не будет работать с собственным классом активности?

Cpp: (отредактировано)

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();
}


Ява:

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();
    }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
727
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

com.thor.kalen.MainActivity.SendNotification () Java-метод должен вызываться для задание класса com.thor.kalen.MainActivity, а не для jclass этого объекта: это не метод статический:

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

Обратите внимание на комментарий в 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;

Кроме того, вы можете только показывать() AlertDialog из основного (UI) потока. Ваш код C++ предполагает, что вы делаете это из фонового потока.

Если этот код выполняется в основном потоке, то

main_activity->vm->DetachCurrentThread()

следует удалить. AttachThread () тоже можно удалить, но это NOP при вызове в уже присоединенном потоке.

Я попытался заменить диалоговое окно предупреждения на int x = 0; и он все еще вылетает, похоже, даже не доходит.

Skrakle 28.05.2018 23:04

Кроме того, я звоню из android_main.

Skrakle 28.05.2018 23:11

Ты прав! Я перепутал объект и класс, теперь он работает, большое вам спасибо!

Skrakle 29.05.2018 12:49

Другие вопросы по теме