安卓如何将参数传递给本地活动?

12

我的Android应用包括两个活动:“.MainActivity”和“android.app.NativeActivity”。后者纯粹由C++实现。在“.MainActivity”中点击按钮后,我尝试启动一个本地活动并传递一些参数:

public void pressedButton(View view)
{
    Intent intent = new Intent(this, android.app.NativeActivity.class);
    intent.putExtra("MY_PARAM_1", 123);
    intent.putExtra("MY_PARAM_2", 321);
    startActivity(intent);
}

在android.app.NativeActivity的入口点(即C函数void android_main(struct android_app* state))中,如何获取MY_PARAM_1和MY_PARAM_2?

1个回答

16

android_app结构中有一个名为activity的数据成员,其类型为ANativeActivity*。在后者内部,有一个名为vmJavaVM*和一个误导性地称为clazzjobject指针。实际上,clazz是指向类型为android.app.NativeActivity的Java对象的JNI兼容对象实例指针,该对象具有所有Activity方法,包括getIntent()

这里也有一个JNIEnv,但看起来它未附加到活动的主线程上。

使用JNI调用来检索意图,然后从意图中提取额外信息。操作如下:

JNIEnv *env;
state->activity->vm->AttachCurrentThread(&env, 0);

jobject me = state->activity->clazz;

jclass acl = env->GetObjectClass(me); //class pointer of NativeActivity
jmethodID giid = env->GetMethodID(acl, "getIntent", "()Landroid/content/Intent;");
jobject intent = env->CallObjectMethod(me, giid); //Got our intent

jclass icl = env->GetObjectClass(intent); //class pointer of Intent
jmethodID gseid = env->GetMethodID(icl, "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");

jstring jsParam1 = (jstring)env->CallObjectMethod(intent, gseid, env->NewStringUTF("MY_PARAM_1"));
const char *Param1 = env->GetStringUTFChars(jsParam1, 0);
//When done with it, or when you've made a copy
env->ReleaseStringUTFChars(jsParam1, Param1);

//Same for Param2

谢谢。但是它引发了另一个我不清楚的问题:我可以直接使用 state->activity->env 吗,还是必须使用 state->activity->vm->AttachCurrentThread(&env, 0); 来获取它? - Nick
嗯...我正在查看线程启动代码(在android_native_app_glue.c中),看起来它没有附加到本地活动线程。所以,是的,你必须先将JVM附加到线程上,而不是使用env。编辑了答案。 - Seva Alekseyev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接