Handler
Handler,? 快遞員
MessageQueen? 投遞站
Looper? 理解為報告系統(tǒng)
通過Handler 可以發(fā)快遞,也可以收快遞
handMessage 對應: 投遞員從投遞站中取到快件后會根據(jù)快件的信息送到客戶手中,
sendMessage 對應: 投遞員從多個客戶手中收到要寄送的快遞,送回自己所屬的快遞站
looper? 對應: 快遞站每隔一定時間會來一輛拖運車將快遞站收到的快遞一件一件的拉走,發(fā)到目標地的快遞站
目的地的快遞員從從投遞站中取到快件后會根據(jù)快件的信息送到客戶手中,這一步又回到handMessage
快遞員只能處理所屬公司快遞站的快件進行投或送
Handler只能處理自己歸屬MessageQueen收發(fā)的Message
? ? 快遞公司只能讓一套物流輪循系統(tǒng)收集自己屬下快遞站的快件,不可能有多個分支物流同時處理
當前線程,只能有一個looper來循環(huán)MessageQueen進行收發(fā)消息
一個線程只能有一個looper, prepare為創(chuàng)建looper的方法
public static void prepare() {
? ? prepare(true);
}
private static void prepare(boolean quitAllowed) {
? ? if (sThreadLocal.get() != null) {
? ? ? ? throw new RuntimeException("Only one Looper may be created per thread");
//每個線程只能有一個looper存在
? ? }
? ? sThreadLocal.set(new Looper(quitAllowed));
}
快遞站建立,物流系統(tǒng)必備的,
looper創(chuàng)建的時候伴生著Messagequeen
private Looper(boolean quitAllowed) {
? ? mQueue = new MessageQueue(quitAllowed);
? ? mThread = Thread.currentThread();
}
一個looper對應一個Messagequeen
快遞公司新開辟市場,想新招快遞員,這個時候因為當?shù)氐奈锪髡具€未建立,沒有物流系統(tǒng),那么快遞員這個時候是沒有服務對象,還沒有正式加入到物流鏈中,所以這個時候新招快遞員是個失敗的決策
在子線程中直接創(chuàng)建Handler會報異常,因為looper還沒有創(chuàng)建,
因為在創(chuàng)建handler的過程中會去取當前線程的looper對象,直接創(chuàng)建的話lopper對象還沒有創(chuàng)建出來,所以會報異常.
所以,要想在子線程中創(chuàng)建handler,必須先調(diào)用looper.prepare方法先創(chuàng)建出looper來
public Handler(Callback callback, boolean async) {
? ? if (FIND_POTENTIAL_LEAKS) {
? ? ? ? final Class<? extends Handler> klass = getClass();
? ? ? ? if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
? ? ? ? ? ? ? ? (klass.getModifiers() & Modifier.STATIC) == 0) {
? ? ? ? ? ? Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
? ? ? ? ? ? ? ? klass.getCanonicalName());
? ? ? ? }
? ? }
? ? mLooper = Looper.myLooper(); //此處獲取當前線程的looper
? ? if (mLooper == null) {
? ? ? ? throw new RuntimeException(
? ? ? ? ? ? "Can't create handler inside thread " + Thread.currentThread()
? ? ? ? ? ? ? ? ? ? + " that has not called Looper.prepare()");
? ? }
? ? mQueue = mLooper.mQueue;
? ? mCallback = callback;
? ? mAsynchronous = async;
}
所以正確的打開姿勢:
new Thread(new Runnable() {
? ? @Override
? ? public void run() {
? ? ? ? Looper.prepare();? //創(chuàng)建物流站,對接物流系統(tǒng)
? ? ? ? Handler handler = new Handler();//招聘快遞員
? ? ? ? Looper.loop();? //啟動物流系統(tǒng)
? ? }
}).start();