gpt4 book ai didi

Android 4.1虚拟键盘卡住

转载 作者:行者123 更新时间:2023-11-30 03:48:11 29 4
gpt4 key购买 nike

我有以下仅在 Android 4.1 上出现的奇怪问题:当虚拟键盘打开并且用户按下“返回”按钮时,我的应用程序只是卡住并且不再有反应。过了一会儿,弹出一个系统对话框,通知我该应用程序已死亡并将被关闭。我很难想象这是 Android 中的一个错误,因为通过按 BACK 按钮隐藏键盘是应该可以正常工作的基本功能。不过,我的代码非常小,几乎可以完全排除代码中的错误。

这是我的代码供您查看:

static int quit = 0;

static void engine_handle_cmd(struct android_app *app, int32_t cmd)
{
switch(cmd) {
case APP_CMD_TERM_WINDOW:
quit = 1;
break;
}
}

static int32_t engine_handle_input(struct android_app *app, AInputEvent *event)
{
switch(AInputEvent_getType(event)) {
case AINPUT_EVENT_TYPE_MOTION: {
int action = AMotionEvent_getAction(event);
if((action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_DOWN) showkeyboard(app);
break;
}
}

return 0;
}

void android_main(struct android_app* state)
{
int events, fd;
struct android_poll_source *source;

app_dummy();

state->onAppCmd = engine_handle_cmd;
state->onInputEvent = engine_handle_input;

while(!quit) {
if(ALooper_pollOnce(-1, &fd, &events, (void **) &source) >= 0) {
if(source) source->process(state, source);
}
}

exit(0);
}

showkeyboard() 函数在 JNI 中的实现方式如下:

static void showkeyboard(struct android_app* state)
{
// Attaches the current thread to the JVM.
jint lResult;
jint lFlags = 0;
JavaVM *lJavaVM = state->activity->vm;
JNIEnv *lJNIEnv = state->activity->env;
JavaVMAttachArgs lJavaVMAttachArgs;
jobject lNativeActivity, INPUT_METHOD_SERVICE;
jclass ClassNativeActivity, ClassContext;
jfieldID FieldINPUT_METHOD_SERVICE;
JNIEnv *env;
int attached = 0;

// must check if we're already attached!
switch((*lJavaVM)->GetEnv(lJavaVM, (void**) &env, JNI_VERSION_1_6)) {
case JNI_OK:
break;
case JNI_EDETACHED:
lJavaVMAttachArgs.version = JNI_VERSION_1_6;
lJavaVMAttachArgs.name = "NativeThread";
lJavaVMAttachArgs.group = NULL;

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

attached = 1;
break;

case JNI_EVERSION:
return; // Invalid Java version
}

// Retrieves NativeActivity.
lNativeActivity = state->activity->clazz;
ClassNativeActivity = (*lJNIEnv)->GetObjectClass(lJNIEnv, lNativeActivity);

// Retrieves Context.INPUT_METHOD_SERVICE.
ClassContext = (*lJNIEnv)->FindClass(lJNIEnv, "android/content/Context");

FieldINPUT_METHOD_SERVICE = (*lJNIEnv)->GetStaticFieldID(lJNIEnv, ClassContext, "INPUT_METHOD_SERVICE", "Ljava/lang/String;");
INPUT_METHOD_SERVICE = (*lJNIEnv)->GetStaticObjectField(lJNIEnv, ClassContext, FieldINPUT_METHOD_SERVICE);
{
// Runs getSystemService(Context.INPUT_METHOD_SERVICE).
jclass ClassInputMethodManager = (*lJNIEnv)->FindClass(lJNIEnv, "android/view/inputmethod/InputMethodManager");
jmethodID MethodGetSystemService = (*lJNIEnv)->GetMethodID(lJNIEnv, ClassNativeActivity, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
jobject lInputMethodManager = (*lJNIEnv)->CallObjectMethod(lJNIEnv, lNativeActivity, MethodGetSystemService, INPUT_METHOD_SERVICE);

// Runs getWindow().getDecorView().
jmethodID MethodGetWindow = (*lJNIEnv)->GetMethodID(lJNIEnv, ClassNativeActivity, "getWindow", "()Landroid/view/Window;");
jobject lWindow = (*lJNIEnv)->CallObjectMethod(lJNIEnv, lNativeActivity, MethodGetWindow);
jclass ClassWindow = (*lJNIEnv)->FindClass(lJNIEnv, "android/view/Window");
jmethodID MethodGetDecorView = (*lJNIEnv)->GetMethodID(lJNIEnv, ClassWindow, "getDecorView", "()Landroid/view/View;");
jobject lDecorView = (*lJNIEnv)->CallObjectMethod(lJNIEnv, lWindow, MethodGetDecorView);

// Runs lInputMethodManager.showSoftInput(...).
jmethodID MethodShowSoftInput = (*lJNIEnv)->GetMethodID(lJNIEnv, ClassInputMethodManager, "showSoftInput", "(Landroid/view/View;I)Z");
(*lJNIEnv)->CallBooleanMethod(lJNIEnv, lInputMethodManager, MethodShowSoftInput, lDecorView, lFlags);

if(attached) {
// Finished with the JVM.
(*lJavaVM)->DetachCurrentThread(lJavaVM);
}
}
}

要重现,您只需编译应用程序,将其与 Android 4.1 图像一起放到模拟器上,然后单击某处,虚拟键盘就会显示出来。现在尝试使用 BACK 按钮关闭键盘。该应用程序现在将卡住。

请注意,此错误仅发生在 Android 4.1 上。它在 2.3、3.0 和 4.0 上运行良好。这可能是 Android 本身的一个主要错误吗?我真的没有其他解释,因为我的代码实际上只是一个根本不做任何事情的原始主循环。但是,尝试关闭虚拟键盘仍然会使应用程序崩溃。

非常感谢您对这个问题的帮助!我已经为此苦苦挣扎了几个小时:(

更新 1:该问题也出现在 Android 4.2 上。已在 Android 问题站点上打开一张票。每个遇到同样问题的人都应该在票上发表评论,以便 Android 开发人员意识到这一点。链接在这里: http://code.google.com/p/android/issues/detail?id=43817&thanks=43817&ts=1359632204

最佳答案

谢谢你提出这个问题,它对我有帮助。

我也看到了卡住。它似乎来自 android_native_app_glue.c 中 process_input 中的 AInputQueue_preDispatchEvent。为了解决这个问题,我改变了:

LOGI("New input event: type=%d\n", AInputEvent_getType(event));
if (AInputQueue_preDispathEvent(app->inputQueue, event)) {
return;
}
int32_t handled = 0;

到:

int32_t type = AInputEvent_getType(event);
LOGI("New input event: type=%d\n", type);
if (!g_iShowingSoftKeyboard || (type != AINPUT_EVENT_TYPE_KEY)
|| (AKeyEvent_getKeyCode(event) != AKEYCODE_BACK))
{
if (AInputQueue_preDispathEvent(app->inputQueue, event)) {
return;
}
}
int32_t handled = 0;

当然,g_iShowingSoftKeyboard 是我正在使用的全局变量,如果显示软键盘,则为 true。

编辑:然后关闭软键盘,我在输入处理程序中处理后退键。

关于Android 4.1虚拟键盘卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14607036/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com