我一般創(chuàng)建Handler 是這樣創(chuàng)建的
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();
但是就很疑惑,在主線程中創(chuàng)建的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對象,一直循環(huán)取的也是主線程中的MessageQueue對象,所以如果是子線程的情況,需要主動調(diào)用下loop方法才行。
在Handler中有send和post方法,這兩個有什么區(qū)別呢
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);
}
區(qū)別是在這里
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();
}