Android源碼學習(1) Handler

來源:互聯網
上載者:User

標籤:hat   empty   操作   targe   android源碼   can   消費者模式   get   llb   

Handler的執行個體化

在安卓開發中,經常會用到Handler將任務提交到指定線程(例如主線程)去執行或者讓其順延強制。Handler的建構函式有多種重載形式,但最終都調用到如下兩種之一:

public Handler(Callback callback, boolean async) {    mLooper = Looper.myLooper();    if (mLooper == null) {        throw new RuntimeException(                "Can‘t create handler inside thread that has not called Looper.prepare()");    }    mQueue = mLooper.mQueue;    mCallback = callback;    mAsynchronous = async;}public Handler(Looper looper, Callback callback, boolean async) {    mLooper = looper;    mQueue = looper.mQueue;    mCallback = callback;    mAsynchronous = async;}

可以看到:這兩個建構函式的區別只是Looper的擷取方式不一樣,當未指定Looper時,Handler內部會通過Looper.myLooper()靜態方法,擷取當前線程的Looper。我們往Handler上發送的Message或者Runnable正是由這個Looper(或該Looper的線程)負責處理的。我們可以通過Looper.getMainLooper()擷取主線程的Looper。

發送Message或者Runnable

調用post、postAtTime、postDelayed提交Runnable,調用sendMessage、sendEmptyMessage、sendMessageDelayed、sendEmptyMessageDelayed、sendMessageAtTime、sendEmptyMessageAtTime發送Message,最終都調用到sendMessageAtTime:

 1 public boolean sendMessageAtTime(Message msg, long uptimeMillis) { 2     MessageQueue queue = mQueue; 3     if (queue == null) { 4         RuntimeException e = new RuntimeException( 5                 this + " sendMessageAtTime() called with no mQueue"); 6         Log.w("Looper", e.getMessage(), e); 7         return false; 8     } 9     return enqueueMessage(queue, msg, uptimeMillis);10 }11 12 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {13     msg.target = this;14     if (mAsynchronous) {15         msg.setAsynchronous(true);16     }17     return queue.enqueueMessage(msg, uptimeMillis);18 }

也就是說,提交的Runnable最終會被封裝成Message,此時Message的callback欄位將指向該Runnable。所有提交的Message都將會被插入名為mQueue的有序隊列中,排序的依據便是傳入的uptimeMillis(該值在enqueueMessage操作中會被賦給Message的when欄位)。MessageQueue使用生產者-消費者模式,post*和send*產生的訊息,最終會被Looper消費。(第2行中將mQueue賦給局部變數queue再通過改變訪問mQueue,顯然是出於多線程並發的安全性考慮)

使用postAtFrontOfQueue、sendMessageAtFrontOfQueue可以分別提交Runnable和Message到mQueue的隊首,該Runnable或者Message將在Looper的下次迴圈中處得到處理。

使用removeCallbacks、removeMessages、removeCallbackAndMessages可以移除掉已經提交的Runnable或者Message。

Android源碼學習(1) Handler

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.