Android 本机 Activity - 调用 Java 方法
Android Native Activity - Call Java method
我已经尝试了一段时间从 c++ 调用 java 方法,我能够使用 Activity class 成功完成,但使用 NativeActivity,调用CallVoidMethod时崩溃。 GetMethodID 是能够找到它的,它 returns 一个地址。 env 和 vm 对象是有效的并且是从 android_main() 填充的。有没有可能它根本无法与原生 activity class 一起使用?
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();
}
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 方法应该为 class 的 jobject 调用com.thor.kalen.MainActivity,不是这个对象的 jclass:它不是 static方法:
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;
此外,您只能从主 (UI) 线程 show() AlertDialog。您的 C++ 代码建议您从后台线程执行。
如果这段代码在主线程上执行,那么
main_activity->vm->DetachCurrentThread()
应该删除。 AttachThread() 也可以删除,但在已附加的线程上调用时它是一个 NOP。
我已经尝试了一段时间从 c++ 调用 java 方法,我能够使用 Activity class 成功完成,但使用 NativeActivity,调用CallVoidMethod时崩溃。 GetMethodID 是能够找到它的,它 returns 一个地址。 env 和 vm 对象是有效的并且是从 android_main() 填充的。有没有可能它根本无法与原生 activity class 一起使用?
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();
}
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 方法应该为 class 的 jobject 调用com.thor.kalen.MainActivity,不是这个对象的 jclass:它不是 static方法:
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;
此外,您只能从主 (UI) 线程 show() AlertDialog。您的 C++ 代码建议您从后台线程执行。
如果这段代码在主线程上执行,那么
main_activity->vm->DetachCurrentThread()
应该删除。 AttachThread() 也可以删除,但在已附加的线程上调用时它是一个 NOP。