Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android AsyncQueryHandler研究

Android AsyncQueryHandler研究

編輯:Android開發實例

今天晚上研究了一下啊AsyncQueryHandler,收獲挺大,記錄下重要知識點,以後繼續補充研究。

研究AsyncQueryHandler這個類的時候遇到了幾個重要的不清楚的知識點

1. Handler與Thread,Looper的關系

2. HandlerThread是干什麼用的

3. ThreadLocal類是干什麼用的

Handler主要是用來發送和處理消息,但是發送了消息後,消息是怎麼傳遞的呢?這就是Looper的作用了,每個Handler中都會有一個Looper對象,如果在創建Handler的時候不指定,系統就會默認將當前線程的Looper綁定到Handler上,Looper對象中維護者一個消息隊列,Hander發送的消息都會存儲到這個消息隊列中,Looper不斷的遍歷這個消息隊列,取出消息,交給handleMessage方法處理。Looper屬於哪個線程,hadleMessage方法就會在那個線程中執行。

HandlerThread不但能提供異步處理,Handler處理消息的方法也會在這個線程中執行,他最要的作用就是提供了一個線程。(這個類還有待研究)

ThreadLocal類主要是用來多個模塊共享變量用的,但是不同線程之間的變量的值卻不相同。

說明1:對象a,對象b比如說是某個類的實例對象,在模塊A,B,C中共享對象a,還有對象b,在線程A中,模塊A中設置a的值,在模塊B,C中取出a的值,三個模塊操作的是同一個值,但是對象a和對象b分別屬於兩個線程,他們是不同的。

AsyncQueryHandler的工作機制是什麼?

AsyncQueryHandler繼承了Handler對象,但是他提供的構造方法中卻沒有Looper參數,也就是說他和他所在的當前線程綁定,AsyncQueryHandler內部有一個Hhandler對象,叫mWorkerHandler,他和一個HandlerThread綁定,mWorkerHandler負責將打包好的消息發送,並且處理,並將結果作為消息發送給AsyncQueryHandler。他是怎麼發送的?AsyncQueryHandler內部有一個WorkerArgs完美類,他封裝了startAsyncQuery等方法的參數,並且通過這行代碼

WorkerArgs args = new WorkerArgs();
       args.handler = this;

將當前Handler封裝進去,發送到HandlerThread中去,mWorkerHandler處理完消息得到結果後,args.handler將結構發送給自己進行處理。(這就是線程間的通信了)
 

mWorkerHandler和一個子線程綁定,能夠處理比較耗時的操作,AsyncQueryHandler提供異步處理。

 

總結:

Handler有兩個作用,Handler用在一個線程中,就是實現異步操作。用在不同的線程之間,那就是異步操作加線程間通信。

補充:

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.

這是一個包含了Looper對象的線程,這個looper可以用來創建Handler對象,記住:start()方法必須被調用,否則通過getLooper方法得到的looper對象是空的。通過調用start方法,就會去執行該線程的run方法, public void run() {

        mTid = Process.myTid();

        Looper.prepare();//創建一個Looper實例,並且存儲在ThreadLocal中,ThreadLocal中維護一個HashMap,鍵是線程號

        synchronized (this) {

            mLooper = Looper.myLooper();//得到當前線程的Looper,就是剛才perpare方法中創建並存儲的那個Looper實例

            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方法給用戶,由用戶自己實現的?

public abstract class AsyncQueryHandler extends Handler  他是一個抽象類


 

MessageQueue是不是一個任務隊列?

是,他是一個優先級隊列(可以通過ArrayList的排序來實現)。它內部自己維護一個ArrayLsit集合,用來存儲Message消息,Message消息有三種,普通消息,按照先發送先執行的FIFO原則進行;高優先級的消息,這種消息會直接插在隊列的最前面,立刻執行;還有一種定時消息,類似於定時任務,到時間才執行。

Looper是如何輪詢MessageQueue的?

當在主線程中使用Handler的時候,不用指定Looper,因為在主線程開啟的時候,就已經調用了Looper.loop()方法開始輪詢了。

擋在子線程中使用Handler的時候,通過調用Looper的prepare方法創建存儲Looper對象,還得調用Looper.loop()方法開啟輪詢。

當配合HandlerThread使用Handler的時候,HandlerThread的run方法中調用了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消息實現了Parcelable接口

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved