Android - 密钥调度超时
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3467205/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android - Key Dispatching Timed Out
提问by Donal Rafferty
In my Android application I am getting a very strange crash, when I press a button (Image) on my UI the entire application freezes and after a couple of seconds I getthe dreaded force close dialog appearing.
在我的 Android 应用程序中,我遇到了一个非常奇怪的崩溃,当我按下 UI 上的一个按钮(图像)时,整个应用程序都冻结了,几秒钟后出现了可怕的强制关闭对话框。
Here is what gets printed in the log:
以下是日志中打印的内容:
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'
This is the code for the 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));
}
});
If I comment the following out the pressing of the button (image) doesn't cause the crash:
如果我注释掉以下按钮(图像)的按下不会导致崩溃:
try {
serviceBinder.endCall(lineId);
} catch (RemoteException e) {
e.printStackTrace();
}
The above code calls down through several levels of the app and into the native layer (NDK), could the call passing through several objects be leading to the force close? It seems unlikely as several other buttons do the same without issue.
上面的代码通过app的几个层次向下调用到native层(NDK),调用通过几个对象会导致强制关闭吗?这似乎不太可能,因为其他几个按钮都可以毫无问题地执行相同操作。
How about the native layer? Could some code I've built with the NDK be causing the issue?
原生层呢?我用 NDK 构建的一些代码会导致这个问题吗?
Any other ideas as to what the cause of the issue might be?
关于问题的原因可能是什么的任何其他想法?
回答by Alex
You must be as fast as possible in your onClick implementation. Expensive operations should be, in general, offloaded to a background thread.
您必须尽可能快地执行 onClick。通常,昂贵的操作应该卸载到后台线程。
In onClick, try:
在 onClick 中,尝试:
Thread t = new Thread(){
public void run(){
your_stuff();
}
};
t.start();
instead of just
而不仅仅是
your_stuff()
回答by juanes
You can encounter this error when you block the main thread (a.k.a. the UI thread) for a few seconds. Expensive operations should be, in general, offloaded to a background thread. AsyncTaskis very helpful in these cases.
当您阻塞主线程(也称为 UI 线程)几秒钟时,您可能会遇到此错误。通常,昂贵的操作应该卸载到后台线程。AsyncTask在这些情况下非常有用。
In your case you could do the following:
在您的情况下,您可以执行以下操作:
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
serviceBinder.endCall(lineId);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}.execute();
回答by Jawad Zeb
Do your long Operation in a seperate thread or use AsyncTask to get rid of ANR.
在单独的线程中执行长时间的操作或使用 AsyncTask 摆脱 ANR。
An ANR(Activity Not Responding)happens when some long operation takes place in the "main"
thread. This is the event loop thread, and if it is busy, Android cannot process any further GUI events in the application, and thus throws up an ANR dialog
.
一个ANR(活动无响应)时会发生一些long operation takes place in the "main"
线索。这是事件循环线程,如果它很忙,Android 将无法处理应用程序中的任何其他 GUI 事件,因此会抛出一个ANR dialog
.
Your activity took to long to say to the Android OS 'hey i'm still alive'! (This is what the UI thread does).
您的活动花了很长时间才对 Android 操作系统说“嘿,我还活着”!(这就是 UI 线程所做的)。
http://developer.android.com/guide/practices/design/responsiveness.html
http://developer.android.com/guide/practices/design/responsiveness.html
Basically if you make the UI thread do some complex task it's too busy doing your task to tell the OS that it is still 'alive'.
基本上,如果你让 UI 线程做一些复杂的任务,它会忙着做你的任务,无法告诉操作系统它仍然“活着”。
http://android-developers.blogspot.co.uk/2009/05/painless-threading.html
http://android-developers.blogspot.co.uk/2009/05/painless-threading.html
You should move your XML Parsing code to another thread, then use a callback to tell the UI thread you have finished and to do something with the result.
您应该将 XML 解析代码移动到另一个线程,然后使用回调告诉 UI 线程您已经完成并处理结果。
http://developer.android.com/resources/articles/timed-ui-updates.html
http://developer.android.com/resources/articles/timed-ui-updates.html
Detecting where ANRs happen is easy if it is a permanent block (deadlock acquiring some locks for instance), but harder if it's just a temporary delay. First, go over your code and look for vunerable spots and long running operations. Examples may include using sockets, locks, thread sleeps, and other blocking operations from within the event thread. You should make sure these all happen in separate threads. If nothing seems the problem, use DDMS and enable the thread view. This shows all the threads in your application similar to the trace you have. Reproduce the ANR, and refresh the main thread at the same time. That should show you precisely whats going on at the time of the ANR
如果它是一个永久块(例如获取一些锁的死锁),则检测 ANR 发生的位置很容易,但如果它只是一个临时延迟,则更难。首先,检查您的代码并寻找易受攻击的地方和长时间运行的操作。示例可能包括在事件线程内使用套接字、锁、线程休眠和其他阻塞操作。您应该确保这些都发生在单独的线程中。如果没有任何问题,请使用 DDMS 并启用线程视图。这将显示您的应用程序中的所有线程,类似于您拥有的跟踪。重现ANR,同时刷新主线程。这应该会准确地向您显示 ANR 发生时的情况
If Logcat doesn't output anything usefull, try to pull traces.txt from /data/anr/traces.txt
如果 Logcat 没有输出任何有用的信息,请尝试从 /data/anr/traces.txt 中提取 traces.txt
adb pull /data/anr/traces.txt .
as it may give more information on where the ANR Exception occurrred
因为它可能会提供有关 ANR 异常发生位置的更多信息
And this linkmay also helpful for creating AsyncTask and Threads
而这个环节也可用于创建的AsyncTask和线程有帮助
回答by Rajesh Narwal
If you are doing a resource intensive task then it might happen. While resuming the Activity. 1. Try stopping all your intensive work on onPause and then restarting it on onResume. 2. If you are showing map on Activity drawing overlay on it then stop refreshing the overlays while on sleep. And then restart it on onResume.
如果您正在执行资源密集型任务,那么它可能会发生。在恢复活动时。1. 尝试停止 onPause 上的所有密集工作,然后在 onResume 上重新启动它。2. 如果您在活动绘图覆盖图上显示地图,则在睡眠时停止刷新覆盖图。然后在 onResume 上重新启动它。