使用本机活动关闭软键盘时崩溃 [英] Crash when closing soft keyboard while using native activity

查看:115
本文介绍了使用本机活动关闭软键盘时崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在为Android开发独立游戏,希望用户选择自己的昵称.我们选择使用NDK提供的本机活动",因为这似乎是最简单的方法.

我们在键盘上遇到的第一个问题是函数ANativeActivity_showSoftInput()似乎根本不起作用(如,不过我们仍然很高兴听到有关解决方法的信息.如果您也受到它的影响,则可能需要对该问题进行投票(按星号).

解决方案

Peter的解决方案效果很好.但是,如果您不想修改native_app_glue文件:请注意,将process_input分配为函数指针.在实现文件中,按照Peter的描述创建自己的process_input函数:

  static void process_input(struct android_app *应用,struct android_poll_source *源){AInputEvent *事件= NULL;if(AInputQueue_getEvent(app-> inputQueue,& event)> == 0){int类型= AInputEvent_getType(事件);LOGV(新输入事件:type =%d \ n",AInputEvent_getType(event));bool skip_predispatch= AInputEvent_getType(事件)== AINPUT_EVENT_TYPE_KEY&&AKeyEvent_getKeyCode(event)== AKEYCODE_BACK;//跳过预调度(所有操作都发送到IME)if(!skip_predispatch&& AInputQueue_preDispatchEvent(app-> inputQueue,event)){返回;}int32_t处理= 0;如果(app-> onInputEvent!= NULL)已处理= app-> onInputEvent(app,event);AInputQueue_finishEvent(app-> inputQueue,事件,已处理);} 别的 {LOGE(读取下一个输入事件失败:%s \ n",strerror(errno));}} 

android_main 函数的开头,将您的 process_input 版本分配给 android_app-> inputPollSource.process .

在事件处理程序中,请确保检查后退键( AKEYCODE_BACK ),并进行拦截以隐藏键盘(如果可见).

请注意,此问题似乎在Android 4.1和4.2中存在-在4.3中已解决

We are developing an indie game for android and would like the user to choose his nickname. We have chosen to use the Native Activity that is provided by the NDK as that seemed to be the easiest way to go.

The first problem we've encountered with the keyboard was that the function ANativeActivity_showSoftInput() seems to do nothing at all (as described e.g. here), so we bring up the keyboard using JNI calls to function:

static void showKeyboard(Activity activity) {
  String s = Context.INPUT_METHOD_SERVICE;
  InputMethodManager m = (InputMethodManager)activity.getSystemService(s);
  View w = activity.getWindow().getDecorView();
  m.showSoftInput(w, 0);
}

This works fine for bringing up the keyboard, and works fine on some devices all together. But on other devices (e.g. Nexus 7), when the user tries to close the keyboard by hitting the "hide keyboard" button the application freezes with this debug output:

I/InputDispatcher(  453): Application is not responding: AppWindowToken{429b54a8 token=Token{42661288 ActivityRecord{41bb0b00 u0 com.example.project/android.app.NativeActivity}}} - Window{420d6138 u0 com.example.project/android.app.NativeActivity}.  It has been 5006.7ms since event, 5005.6ms since wait started.  Reason: Waiting because the focused window has not finished processing the input events that were previously delivered to it.
I/WindowManager(  453): Input event dispatching timed out sending to com.example.project/android.app.NativeActivity

And then the user is presented with a dialog box saying:

Project isn't responding. Do you want to close it? [Wait]/[OK]

Is there something we are doing obviously wrong? Or might this be a bug? Issues like this one seem to suggest keyboard functionality has never been properly implemented in the native glue.

On a side note, we havent tested on many devices yet, but the ones where it doesn't crash are ones with an older android OS. Also, on those where it does crash, when the keyboard appears, it changes the back button from one that looks like this to one that looks like this . Perhaps that corresponds to a different input event that wasn't accounted for when they first developed the native glue? I'm just guessing .

Anyway, if someone got soft keyboard working while using native activity, please let us know how you've done it.

Cheers

UPDATE

It has been reported as a bug in Android here, we would still be happy to hear about workarounds though. If you are also affected by it, you might want to cast a vote on that issue (by pressing the star).

解决方案

Peter's solution works well. However if you don't want to modify the native_app_glue file: notice that process_input is assigned as a function pointer. In your implementation file, create your own process_input functions as described by Peter:

static void process_input( struct android_app* app, struct android_poll_source* source) {
    AInputEvent* event = NULL;
    if (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
        int type = AInputEvent_getType(event);
        LOGV("New input event: type=%d\n", AInputEvent_getType(event));

        bool skip_predispatch
              =  AInputEvent_getType(event)  == AINPUT_EVENT_TYPE_KEY
              && AKeyEvent_getKeyCode(event) == AKEYCODE_BACK;

        // skip predispatch (all it does is send to the IME)
        if (!skip_predispatch && AInputQueue_preDispatchEvent(app->inputQueue, event)) {
            return;
        }

        int32_t handled = 0;
        if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
        AInputQueue_finishEvent(app->inputQueue, event, handled);
    } else {
        LOGE("Failure reading next input event: %s\n", strerror(errno));
    }
}

At the beginning of your android_main function, assign your version of process_input to android_app->inputPollSource.process.

In your event handler make sure you check for the back key (AKEYCODE_BACK) and intercept it to hide your keyboard if visible.

Note that this problem appears to exist in Android 4.1 and 4.2 - solved in 4.3

这篇关于使用本机活动关闭软键盘时崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆