我正在阅读EAT书籍,并且有一个显示queueIdle利用率的代码示例。
下面的代码启动10个线程,每个新线程抛出10个消息。而且我希望在发送每条消息后,looper将被退出。
@Override
public boolean queueIdle() {
if (mIsFirstIdle) {
mIsFirstIdle = false;
return true;
}
mConsumerHandler.getLooper().quit();
return false;
}
“空闲插槽可以在第一条消息之前,消息之间发生, 并在最后一条消息之后。 “摘录自:AndersGöransson。 “高效的Android线程。”iBooks。
所以我认为,queueIdle将使用第一条消息和最后一条消息进行调用,因此它确保每条消息都会被传递。
但我得到了以下错误,因为queueIdle意外调用了??
在死线程上向处理程序发送消息
是正常还是示例代码错了?
代码示例
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.os.SystemClock;
import android.util.Log;
import java.util.Random;
public class ConsumeAndQuitThreadActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ConsumeAndQuitThread consumeAndQuitThread = new ConsumeAndQuitThread();
consumeAndQuitThread.start();
for (int i = 0; i < 10; i++) {
Log.v("EATDEGUB","thread " + i + " started.");
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
Log.v("EATDEGUB","currentThread "+ Thread.currentThread().getId() + " : enqueueData is " + i);
SystemClock.sleep(new Random().nextInt(10));
consumeAndQuitThread.enqueueData(i);
}
}
}).start();
}
}
private static class ConsumeAndQuitThread extends Thread implements MessageQueue.IdleHandler {
private static final String THREAD_NAME = "ConsumeAndQuitThread";
public Handler mConsumerHandler;
private boolean mIsFirstIdle = true;
public ConsumeAndQuitThread() {
super(THREAD_NAME);
}
@Override
public void run() {
Looper.prepare();
mConsumerHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//mIsFirstIdle=true;
Log.v("EATDEGUB","handled message is " + msg.what);
}
};
Looper.myQueue().addIdleHandler(this);
Looper.loop();
}
@Override
public boolean queueIdle() {
Log.v("EATDEGUB","Thread " +currentThread().getId());
if (mIsFirstIdle) {
mIsFirstIdle = false;
return true;
}
Log.v("EATDEGUB", "Thread " +currentThread().getId() + " is closed by calling quit()");
mConsumerHandler.getLooper().quit();
return false;
}
public void enqueueData(int i) {
mConsumerHandler.sendEmptyMessage(i);
}
}
}
日志
02-24 13:54:41.490 thread 0 started.
02-24 13:54:41.490 Thread 9590
02-24 13:54:41.490 thread 1 started.
02-24 13:54:41.490 thread 2 started.
02-24 13:54:41.490 currentThread 9592 : enqueueData is 0
02-24 13:54:41.490 currentThread 9591 : enqueueData is 0
02-24 13:54:41.490 thread 3 started.
02-24 13:54:41.490 currentThread 9593 : enqueueData is 0
02-24 13:54:41.490 thread 4 started.
02-24 13:54:41.490 currentThread 9594 : enqueueData is 0
02-24 13:54:41.490 thread 5 started.
02-24 13:54:41.490 currentThread 9595 : enqueueData is 0
02-24 13:54:41.495 thread 6 started.
02-24 13:54:41.495 currentThread 9596 : enqueueData is 0
02-24 13:54:41.495 thread 7 started.
02-24 13:54:41.495 thread 8 started.
02-24 13:54:41.495 currentThread 9597 : enqueueData is 0
02-24 13:54:41.495 currentThread 9598 : enqueueData is 0
02-24 13:54:41.495 thread 9 started.
02-24 13:54:41.495 currentThread 9599 : enqueueData is 0
02-24 13:54:41.495 currentThread 9600 : enqueueData is 0
02-24 13:54:41.495 currentThread 9598 : enqueueData is 1
02-24 13:54:41.495 handled message is 0
02-24 13:54:41.495 Thread 9590
**02-24 13:54:41.495 Thread 9590 is closed by calling quit()**
After this time, none of remaining message can be delivered. >>
02-24 13:54:41.500 currentThread 9592 : enqueueData is 1
02-24 13:54:41.500 currentThread 9591 : enqueueData is 1
02-24 13:54:41.500 currentThread 9593 : enqueueData is 1
02-24 13:54:41.505 currentThread 9597 : enqueueData is 1
02-24 13:54:41.505 currentThread 9594 : enqueueData is 1
02-24 13:54:41.505 currentThread 9595 : enqueueData is 1
02-24 13:54:41.505 currentThread 9596 : enqueueData is 1
02-24 13:54:41.510 currentThread 9600 : enqueueData is 1
02-24 13:54:41.510 currentThread 9599 : enqueueData is 1
02-24 13:54:41.510 currentThread 9592 : enqueueData is 2
02-24 13:54:41.510 currentThread 9598 : enqueueData is 2
02-24 13:54:41.515 currentThread 9593 : enqueueData is 2
02-24 13:54:41.515 currentThread 9596 : enqueueData is 2
02-24 13:54:41.515 currentThread 9591 : enqueueData is 2
02-24 13:54:41.520 currentThread 9595 : enqueueData is 2
02-24 13:54:41.520 currentThread 9600 : enqueueData is 2
02-24 13:54:41.520 currentThread 9599 : enqueueData is 2
02-24 13:54:41.520 currentThread 9594 : enqueueData is 2
02-24 13:54:41.525 currentThread 9592 : enqueueData is 3
02-24 13:54:41.525 currentThread 9597 : enqueueData is 2
02-24 13:54:41.530 currentThread 9593 : enqueueData is 3
02-24 13:54:41.530 currentThread 9591 : enqueueData is 3
02-24 13:54:41.530 currentThread 9596 : enqueueData is 3
02-24 13:54:41.530 currentThread 9598 : enqueueData is 3
02-24 13:54:41.530 currentThread 9600 : enqueueData is 3
02-24 13:54:41.535 currentThread 9595 : enqueueData is 3
02-24 13:54:41.535 currentThread 9596 : enqueueData is 4
02-24 13:54:41.535 currentThread 9594 : enqueueData is 3
02-24 13:54:41.535 currentThread 9593 : enqueueData is 4
02-24 13:54:41.535 currentThread 9591 : enqueueData is 4
02-24 13:54:41.535 currentThread 9597 : enqueueData is 3
02-24 13:54:41.540 currentThread 9592 : enqueueData is 4
02-24 13:54:41.540 currentThread 9599 : enqueueData is 3
02-24 13:54:41.540 currentThread 9599 : enqueueData is 4
02-24 13:54:41.540 currentThread 9591 : enqueueData is 5
02-24 13:54:41.545 currentThread 9593 : enqueueData is 5
02-24 13:54:41.545 currentThread 9598 : enqueueData is 4
02-24 13:54:41.545 currentThread 9598 : enqueueData is 5
02-24 13:54:41.545 currentThread 9596 : enqueueData is 5
02-24 13:54:41.550 currentThread 9594 : enqueueData is 4
02-24 13:54:41.550 currentThread 9595 : enqueueData is 4
02-24 13:54:41.550 currentThread 9600 : enqueueData is 4
02-24 13:54:41.555 currentThread 9591 : enqueueData is 6
02-24 13:54:41.565 currentThread 9597 : enqueueData is 4
02-24 13:54:41.565 currentThread 9591 : enqueueData is 7
02-24 13:54:41.565 currentThread 9599 : enqueueData is 5
02-24 13:54:41.565 currentThread 9593 : enqueueData is 6
02-24 13:54:41.565 currentThread 9596 : enqueueData is 6
02-24 13:54:41.565 currentThread 9594 : enqueueData is 5
02-24 13:54:41.565 currentThread 9598 : enqueueData is 6
02-24 13:54:41.570 currentThread 9595 : enqueueData is 5
02-24 13:54:41.570 currentThread 9600 : enqueueData is 5
02-24 13:54:41.570 currentThread 9592 : enqueueData is 5
02-24 13:54:41.575 currentThread 9599 : enqueueData is 6
02-24 13:54:41.575 currentThread 9598 : enqueueData is 7
02-24 13:54:41.575 currentThread 9591 : enqueueData is 8
02-24 13:54:41.575 currentThread 9592 : enqueueData is 6
02-24 13:54:41.575 currentThread 9593 : enqueueData is 7
02-24 13:54:41.575 currentThread 9594 : enqueueData is 6
02-24 13:54:41.575 currentThread 9600 : enqueueData is 6
02-24 13:54:41.580 currentThread 9595 : enqueueData is 6
02-24 13:54:41.580 currentThread 9592 : enqueueData is 7
02-24 13:54:41.580 currentThread 9596 : enqueueData is 7
02-24 13:54:41.580 currentThread 9599 : enqueueData is 7
02-24 13:54:41.580 currentThread 9600 : enqueueData is 7
02-24 13:54:41.585 currentThread 9597 : enqueueData is 5
02-24 13:54:41.585 currentThread 9593 : enqueueData is 8
02-24 13:54:41.585 currentThread 9598 : enqueueData is 8
02-24 13:54:41.585 currentThread 9592 : enqueueData is 8
02-24 13:54:41.585 currentThread 9591 : enqueueData is 9
02-24 13:54:41.585 currentThread 9594 : enqueueData is 7
02-24 13:54:41.585 currentThread 9593 : enqueueData is 9
02-24 13:54:41.590 currentThread 9595 : enqueueData is 7
02-24 13:54:41.590 currentThread 9596 : enqueueData is 8
02-24 13:54:41.590 currentThread 9598 : enqueueData is 9
02-24 13:54:41.595 currentThread 9600 : enqueueData is 8
02-24 13:54:41.595 currentThread 9595 : enqueueData is 8
02-24 13:54:41.600 currentThread 9599 : enqueueData is 8
02-24 13:54:41.600 currentThread 9596 : enqueueData is 9
02-24 13:54:41.600 currentThread 9594 : enqueueData is 8
02-24 13:54:41.600 currentThread 9592 : enqueueData is 9
02-24 13:54:41.600 currentThread 9597 : enqueueData is 6
02-24 13:54:41.600 currentThread 9597 : enqueueData is 7
02-24 13:54:41.605 currentThread 9600 : enqueueData is 9
02-24 13:54:41.605 currentThread 9594 : enqueueData is 9
02-24 13:54:41.605 currentThread 9595 : enqueueData is 9
02-24 13:54:41.605 currentThread 9599 : enqueueData is 9
02-24 13:54:41.610 currentThread 9597 : enqueueData is 8
02-24 13:54:41.615 currentThread 9597 : enqueueData is 9
答案 0 :(得分:0)
一年后;)我正在读这本书并且有完全相同的问题。
我的猜测是 sleep 的行正在引入空闲时间
SystemClock.sleep(new Random().nextInt(10));
第二次检测到空闲时间时,MessageQueue调用queueIdle来杀死处理程序并返回false。从现在开始,对sendMessage的所有调用都将在Handler和一个不再存在的Thread上完成,因此错误。
这是我的猜测所以我删除 sleep 的行并启动了应用程序:有时它可以正常工作,但大部分时间错误仍然存在。所以我的猜测是错误的,或者出于不同的原因可能会出现空闲时间。