我一般创建Handler 是这样创建的
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.i("lpc", "----" + Thread.currentThread().getId() + "");
return false;
}});
handler.sendEmptyMessage(0);
这样写法在主线程是没问题的
但如果在子线程中这样些就会报错
new Thread(new Runnable() {
@Override
public void run() {
Handler handler = new Handler(new Handler.Callback() {
@Override
boolean handleMessage(Message msg) {
Log.i("lpc", "----" + Thread.currentThread().getId() + "");
return false;
}
});
handler.sendEmptyMessage(0);
}}).start();
原因是源码中有这样一句
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()");
}
也就是说mLooper为空导致的,需要在实例化Handler之前加上
Looper.prepare();
但是就很疑惑,在主线程中创建的Handler是在什么时候prepare的呢,最终原来是在ActivityThread中有这样一段代码
public static void main(String[] args) {
...
Looper.prepareMainLooper();
...
Looper.loop();
}
prepareMainLooper方法
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}}
ok,加上prepare方法后但是收不到消息,怎么回事?原来还需加上
Looper.loop();
为什么呢,这就需要看下Looper.loop的代码了
public static void loop() {
final Looper me = myLooper();
...
final MessageQueue queue = me.mQueue;
...
for (;;) {
Message msg = queue.next(); // might block
....
msg.target.dispatchMessage(msg);
}
}
因为默认的是主线程的looper,即me对象,一直循环取的也是主线程中的MessageQueue对象,所以如果是子线程的情况,需要主动调用下loop方法才行。
在Handler中有send和post方法,这两个有什么区别呢
send方法和post方法实际上最终都会走到这个方法里面
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
区别是在这里
public final boolean post(Runnable r){
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
实际上也是一个Message对象,只不过他的callback的值就是传入的Runnable,然后在Looper的loop方法中有这样一句代码
msg.target.dispatchMessage(msg);
所以最终会走到
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
handleCallBack方法
private static void handleCallback(Message message) {
message.callback.run();
}