Android - 密钥调度超时

Don*_*rty 37 android timeout key freeze dispatch

在我的Android应用程序中,我遇到了一个非常奇怪的崩溃,当我在我的UI上按下一个按钮(图像)时,整个应用程序冻结,几秒钟后我就会出现可怕的强制关闭对话框.

以下是在日志中打印的内容:


WARN/WindowManager(88): Key dispatching timed out sending to package name/Activity
WARN/WindowManager(88): Dispatch state: {{KeyEvent{action=1 code=5 repeat=0 meta=0 scancode=231 mFlags=8} to Window{432bafa0 com.android.launcher/com.android.launcher.Launcher paused=false} @ 1281611789339 lw=Window{432bafa0 com.android.launcher/com.android.launcher.Launcher paused=false} lb=android.os.BinderProxy@431ee8e8 fin=false gfw=true ed=true tts=0 wf=false fp=false mcf=Window{4335fc58 package name/Activity paused=false}}}
WARN/WindowManager(88): Current state:  {{null to Window{4335fc58 package name/Activity paused=false} @ 1281611821193 lw=Window{4335fc58 package name/Activity paused=false} lb=android.os.BinderProxy@434c9bd0 fin=false gfw=true ed=true tts=0 wf=false fp=false mcf=Window{4335fc58 package name/Activity paused=false}}}
INFO/ActivityManager(88): ANR in process: package name (last in package name)
INFO/ActivityManager(88): Annotation: keyDispatchingTimedOut
INFO/ActivityManager(88): CPU usage:
INFO/ActivityManager(88): Load: 5.18 / 5.1 / 4.75
INFO/ActivityManager(88): CPU usage from 7373ms to 1195ms ago:
INFO/ActivityManager(88):   package name: 6% = 1% user + 5% kernel / faults: 7 minor
INFO/ActivityManager(88):   system_server: 5% = 4% user + 1% kernel / faults: 27 minor
INFO/ActivityManager(88):   tiwlan_wifi_wq: 3% = 0% user + 3% kernel
INFO/ActivityManager(88):   mediaserver: 0% = 0% user + 0% kernel
INFO/ActivityManager(88):   logcat: 0% = 0% user + 0% kernel
INFO/ActivityManager(88): TOTAL: 12% = 5% user + 6% kernel + 0% softirq
INFO/ActivityManager(88): Removing old ANR trace file from /data/anr/traces.txt
INFO/Process(88): Sending signal. PID: 1812 SIG: 3
INFO/dalvikvm(1812): threadid=7: reacting to signal 3
INFO/dalvikvm(1812): Wrote stack trace to '/data/anr/traces.txt'
Run Code Online (Sandbox Code Playgroud)

这是Button(Image)的代码:


findViewById(R.id.endcallimage).setOnClickListener(new OnClickListener() {
                    public void onClick(View v) {
                        mNotificationManager.cancel(2);

                        Log.d("Handler", "Endcallimage pressed");

                        if(callConnected)
                        elapsedTimeBeforePause = SystemClock.elapsedRealtime() - stopWatch.getBase();

                        try {
                            serviceBinder.endCall(lineId);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        } 
                            dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.FLAG_SOFT_KEYBOARD));
                            dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));
                    }
            });     
Run Code Online (Sandbox Code Playgroud)

如果我评论以下内容,按下按钮(图像)不会导致崩溃:


try {
      serviceBinder.endCall(lineId);
    } catch (RemoteException e) {
      e.printStackTrace();
    } 
Run Code Online (Sandbox Code Playgroud)

上面的代码调用了应用程序的几个级别并进入本机层(NDK),通过几个对象的调用是否会导致强制关闭?似乎不太可能,因为其他几个按钮没有问题.

原生层怎么样?我用NDK构建的一些代码是否会导致问题?

关于问题的原因可能是什么?

小智 46

您必须在onClick实现中尽可能快.通常,昂贵的操作应该卸载到后台线程.

在onClick中,尝试:

Thread t = new Thread(){
    public void run(){
        your_stuff();
    }
};
t.start();
Run Code Online (Sandbox Code Playgroud)

而不仅仅是

your_stuff()
Run Code Online (Sandbox Code Playgroud)


jua*_*nes 5

当您阻止主线程(也称为UI线程)几秒钟时,您可能会遇到此错误.通常,昂贵的操作应该卸载到后台线程.在这些情况下,AsyncTask非常有用.

在您的情况下,您可以执行以下操作:

new AsyncTask<Void, Void, Void>() {
    @Override
    protected Void doInBackground(Void... params) {
        try {
            serviceBinder.endCall(lineId);
        } catch (RemoteException e) {
            e.printStackTrace();
        } 
    }
}.execute();
Run Code Online (Sandbox Code Playgroud)