今天晚上研究了一下啊AsyncQueryHandler,,收獲挺大,,記錄下重要知識(shí)點(diǎn),以后繼續(xù)補(bǔ)充研究,。 研究AsyncQueryHandler這個(gè)類的時(shí)候遇到了幾個(gè)重要的不清楚的知識(shí)點(diǎn)
總結(jié): Handler有兩個(gè)作用,,Handler用在一個(gè)線程中,,就是實(shí)現(xiàn)異步操作。用在不同的線程之間,,那就是異步操作加線程間通信,。 補(bǔ)充: HandlerThread: 先看他的類描述:Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called. 這是一個(gè)包含了Looper對象的線程,這個(gè)looper可以用來創(chuàng)建Handler對象,,記?。簊tart()方法必須被調(diào)用,否則通過getLooper方法得到的looper對象是空的,。通過調(diào)用start方法,,就會(huì)去執(zhí)行該線程的run方法, public void run() { mTid = Process.myTid(); Looper.prepare();//創(chuàng)建一個(gè)Looper實(shí)例,,并且存儲(chǔ)在ThreadLocal中,,ThreadLocal中維護(hù)一個(gè)HashMap,鍵是線程號(hào) synchronized (this) { mLooper = Looper.myLooper();//得到當(dāng)前線程的Looper,,就是剛才perpare方法中創(chuàng)建并存儲(chǔ)的那個(gè)Looper實(shí)例 Process.setThreadPriority(mPriority); notifyAll(); } onLooperPrepared(); Looper.loop();//開始輪詢 mTid = -1; } public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); } public static final Looper myLooper() { return (Looper)sThreadLocal.get(); } AsyncQueryHandler是如何提供onxxxComplete方法給用戶,,由用戶自己實(shí)現(xiàn)的,? public abstract class AsyncQueryHandler extends Handler 他是一個(gè)抽象類 MessageQueue是不是一個(gè)任務(wù)隊(duì)列? 是,,他是一個(gè)優(yōu)先級隊(duì)列(可以通過ArrayList的排序來實(shí)現(xiàn)),。它內(nèi)部自己維護(hù)一個(gè)ArrayLsit集合,用來存儲(chǔ)Message消息,,Message消息有三種,,普通消息,按照先發(fā)送先執(zhí)行的FIFO原則進(jìn)行,;高優(yōu)先級的消息,,這種消息會(huì)直接插在隊(duì)列的最前面,立刻執(zhí)行,;還有一種定時(shí)消息,,類似于定時(shí)任務(wù),到時(shí)間才執(zhí)行,。 Looper是如何輪詢MessageQueue的,? 當(dāng)在主線程中使用Handler的時(shí)候,不用指定Looper,,因?yàn)樵谥骶€程開啟的時(shí)候,,就已經(jīng)調(diào)用了Looper.loop()方法開始輪詢了。 擋在子線程中使用Handler的時(shí)候,,通過調(diào)用Looper的prepare方法創(chuàng)建存儲(chǔ)Looper對象,,還得調(diào)用Looper.loop()方法開啟輪詢。 當(dāng)配合HandlerThread使用Handler的時(shí)候,,HandlerThread的run方法中調(diào)用了Looper.loop()方法,。 public static final void loop() { Looper me = myLooper(); MessageQueue queue = me.mQueue; while (true) { Message msg = queue.next(); // might block //if (!me.mRun) { // break; //} if (msg != null) { if (msg.target == null) { // No target is a magic identifier for the quit message. return; } msg.target.dispatchMessage(msg); msg.recycle(); } } } Message消息實(shí)現(xiàn)了Parcelable接口
|
|