android handler 調用原理

1,調度原理

andriod提供了Handler 和 Looper 來知足線程間的通訊。Handler先進先出原則。Looper類用來管理特定線程內對象之間的消息交換(MessageExchange)。java

1)Looper: 一個線程能夠產生一個Looper對象,由它來管理此線程裏的MessageQueue(消息隊列)。android

2)Handler: 你能夠構造Handler對象來與Looper溝通,以便push新消息到MessageQueue裏;或者接收Looper從Message Queue取出)所送來的消息。ide

3) Message Queue(消息隊列):用來存放線程放入的消息。函數

4)線程:UIthread 一般就是main thread,而Android啓動程序時會替它創建一個MessageQueue。oop

1.Handler建立消息 
每個消息都須要被指定的Handler處理,經過Handler建立消息即可以完成此功能。Android消息機制中引入了消息池。Handler建立消息時首先查詢消息池中是否有消息存在,若是有直接從消息池中取得,若是沒有則從新初始化一個消息實例。使用消息池的好處是:消息不被使用時,並不做爲垃圾回收,而是放入消息池,可供下次Handler建立消息時使用。消息池提升了消息對象的複用,減小系統垃圾回收的次數。post

2.Handler發送消息 
UI主線程初始化第一個Handler時會經過ThreadLocal建立一個Looper,該Looper與UI主線程一一對應。使用ThreadLocal的目的是保證每個線程只建立惟一一個Looper。以後其餘Handler初始化的時候直接獲取第一個Handler建立的Looper。Looper初始化的時候會建立一個消息隊列MessageQueue。至此,主線程、消息循環、消息隊列之間的關係是1:1:1。spa

Hander持有對UI主線程消息隊列MessageQueue和消息循環Looper的引用,子線程能夠經過Handler將消息發送到UI線程的消息隊列MessageQueue中。.net

3.Handler處理消息 
UI主線程經過Looper循環查詢消息隊列UI_MQ,當發現有消息存在時會將消息從消息隊列中取出。首先分析消息,經過消息的參數判斷該消息對應的Handler,而後將消息分發到指定的Handler進行處理。線程

2,調度函數

關於android中Handler的postDelayed方法和removeCallbacks方法的使用code

方法postDelayed的做用是延遲多少毫秒後開始運行,而removeCallbacks方法是刪除指定的Runnable對象,使線程對象中止運行。

方法聲明以下:

public final boolean postDelayed (Runnable r, long delayMillis) 其中參數Runnable r在Handler對象所運行的線程中執行。
  • 1
  • 2
  • 1
  • 2

實例

public class HandlerActivity extends Activity { private Button mStartBtn; private Button mRemoveBtn; private int count = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.handler_test); // UI線程(即主線程) Log.e("1", Thread.currentThread().getName()); mStartBtn = (Button)findViewById(R.id.start); mStartBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 在主線程中,啓動一個子線程 Thread startThread = new Thread(countRunnable); startThread.start(); // 主線程 Log.e("Thread.currentThread().getName()", Thread.currentThread().getName()+">>>>>>>>>>>>>>>>end"); } }); mRemoveBtn = (Button)findViewById(R.id.remove); mRemoveBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mHandler.removeCallbacks(countRunnable); } }); } private Handler mHandler = new Handler(); Runnable countRunnable = new Runnable() { @Override public void run() { Log.e("2", Thread.currentThread().getName()); count++; Log.e("!", "count=" + count); //延遲一秒,將Runnable放到主線程中執行(所以,若是是經過postDelayed方法啓動一個Runnable的話,該Runnable對象是能夠更新UI的) mHandler.postDelayed(countRunnable, 1000); } }; }
相關文章
相關標籤/搜索