ANR 的一个触摸bug转载下。。点击就会出现 error 的bug。。

转载 http://ps3computing.blogspot.ca/2012/12/anr-application-not-responding.html 



ANR: Application Not Responding (keyDispatchingTimedOut)

This is a heads up for those Android developers that use the NDK (Native Development Kit) to write Android apps. If you are using the NDK, you are almost certainly using the glue code that Google provides in the android_native_app_glue.c file.

Chances are that in your Google Play Developer Console, you see reports of Application Not Responding (ANR keyDispatchingTimedOut.) For my app, I have 756 of these reports on an installed base of 1.5M downloads. Consulting stackoverflow or other developer groups, will invariably yield the advice not to block the main thread. However, it is easy to cause this ANR without blocking the main thread, if you are using the android_native_app_glue.c file in your project.

If two events are generated at exactly the same time, using different sources or devices, the app will freeze. You can easily produce this with a PS3 controller hooked up to your Android device and depress both analogue sticks at exactly the same time, or release them at exactly the same time. If you do this while running an NDK based app, the app will freeze and issue an ANR.

It took me a day of debugging to find a work around for this, but I am happy to report that the following change to the glue code will stop the issue from happening. What you need to do is get events from the queue repeatedly in a loop, instead of just handling a single event in process_input() function.

static void process_input(struct android_app* app, struct android_poll_source* source)
{
    AInputEvent* event = NULL;
    while ( AInputQueue_hasEvents( app->inputQueue ) )
    {
        if ( AInputQueue_getEvent( app->inputQueue, &event ) >= 0 )
        {
            int32_t handled = 0;
            uint32_t devid = AInputEvent_getDeviceId( event );
            uint32_t src   = AInputEvent_getSource( event );
            //LOGV("New input event: type=%d devid=%x src=%x\n", AInputEvent_getType(event), devid, src);
            int32_t predispatched = (AInputQueue_preDispatchEvent(app->inputQueue, event));
            if (app->onInputEvent != NULL && !predispatched) handled = app->onInputEvent(app, event);
            if (!predispatched) AInputQueue_finishEvent(app->inputQueue, event, handled);
        }
    }
}

I have reported the issue to Google.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值