自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android處理程序:Handler Looper Message源碼研究

移動開發(fā) Android
Looper是消費者,Handler是生產(chǎn)者(同時Looper消費后,也會通知Handler),MessageQueue是消息隊列,隊列的實現(xiàn)方式是鏈表,Message是鏈表的一個節(jié)點。 我們的程序基本上之和Handler打交道。

線程Thread的線程變量ThreadLocal中,存放著這個線程的Looper;Looper在初始化時,會新建一個消息隊列MessageQueue,之后Looper進(jìn)入一個死循環(huán),等待從消息隊列MessageQueue取得消息Message(Looper是消費者),沒有消息時會阻塞;

我們程序中的Handler,會通過sendMessage或post方法,往MessageQueue中添加消息時,添加的這個Message,會記錄他是屬于哪個Handler發(fā)出的,同時根據(jù)message.when,決定新添加的這個Message在Queue中的位置,MessageQueue中只有一個當(dāng)前的Message,隊列關(guān)系是通過Message中的prev,next維護(hù)的,Message是一個鏈表的節(jié)點;

添加消息后,消費者Looper取得Message,并調(diào)用建立Message的Hander的dispatchMessage方法。

咋一看好像Handler即sendMessage,又handlerMessage,事情還是只有一個線程在做事情。

但是后來想想,明白了這樣設(shè)計的必要性。

因為這個***的線程一般而言,都是mainUI線程,如果你有個可以分成多個小任務(wù)的任務(wù)要處理,你沒有使用Handler,直接執(zhí)行,也許系統(tǒng)忙于處理你這個任務(wù),而無法及時響應(yīng)用戶事件,從而導(dǎo)致ANR的拋出。

如果你把你的任務(wù)拆成幾個小任務(wù),用Handler來實現(xiàn),那么系統(tǒng)就可以把你的小任務(wù)推到后面來處理,抽出時間來響應(yīng)用戶操作。

如果真的有大任務(wù),一般式需要另外線程去處理,或者開啟Service。

一個在新線程中使用handler例子,我們來分析下源碼

Java代碼

  1. new Thread(new Runnable() { 
  2. @Override public void run() { 
  3. Handler handler; 
  4. //1、初始化Looper 
  5. Looper.prepare(); 
  6. //2、綁定handler到CustomThread實例的Looper對象、定義處理消息的方法 
  7. handlernew Handler() { 
  8. @Override public void handleMessage(Message msg) { 
  9. }; 
  10. // 3、發(fā)送消息 
  11. handler.sendMessage(new Message()); 
  12. handler.post(new Runnable()) 
  13. handler.obtainMessage(1, "hello").sendToTarget(); 
  14. //4、啟動消息循環(huán) 
  15. Looper.loop(); 
  16. }).start(); 

1 Java代碼

  1. public static final void prepare() { 
  2. if (sThreadLocal.get() != null) { // 每個線程,只能有一個Looper對象 
  3. throw new RuntimeException("Only one Looper may be created per thread"); 
  4. // 如果當(dāng)前線程沒有Looper,新建一個,構(gòu)造函數(shù)是private的 
  5. sThreadLocal.set(new Looper()); 
  6. private Looper() { 
  7. mQueue = new MessageQueue(); // 建立消息隊列 
  8. mRun = true
  9. mThread = Thread.currentThread(); 

2 Java代碼

  1. public Handler(){ 
  2. mLooper = Looper.myLooper(); // 取得當(dāng)前線程的Looper,如果拋異常 
  3. if (mLooper == null) { 
  4. throw new RuntimeException( 
  5. "Can't create handler inside thread that has not called Looper.prepare()"); 
  6. mQueue = mLooper.mQueue; // 取得消息隊列 
  7. mCallback = null

3 Java代碼

  1. //不管調(diào)用哪個方法,最終執(zhí)行的是 
  2. public boolean sendMessageAtTime(Message msg, long uptimeMillis){ 
  3. boolean sent = false
  4. // 取得消息隊列 
  5. MessageQueue queue = mQueue; 
  6. if (queue != null) { 
  7. msg.target = this// 消息發(fā)出著是自己 
  8. sent = queue.enqueueMessage(msg, uptimeMillis); // 添加到消息隊列中 
  9. else { 
  10. RuntimeException e = new RuntimeException( 
  11. this + " sendMessageAtTime() called with no mQueue"); 
  12. Log.w("Looper", e.getMessage(), e); 
  13. return sent; 
  14. final boolean enqueueMessage(Message msg, long when) { 
  15. if (msg.when != 0) { 
  16. throw new AndroidRuntimeException(msg 
  17. " This message is already in use."); 
  18. if (msg.target == null && !mQuitAllowed) { 
  19. throw new RuntimeException("Main thread not allowed to quit"); 
  20. synchronized (this) { 
  21. if (mQuiting) { 
  22. RuntimeException e = new RuntimeException( 
  23. msg.target + " sending message to a Handler on a dead thread"); 
  24. Log.w("MessageQueue", e.getMessage(), e); 
  25. return false
  26. else if (msg.target == null) { 
  27. mQuiting = true
  28. msg.when = when; 
  29. Message p = mMessages; 
  30. // 之前沒有其他消息了,MessageQueue中當(dāng)前消息mMessages 就是傳遞進(jìn)來的msg 
  31. if (p == null || when == 0 || when < p.when) {  
  32. msg.next = p; 
  33. mMessages = msg; 
  34. this.notify(); // 喚醒  
  35. else {  
  36. // 之前有其他消息了,將傳遞的msg放到適合的位置,根據(jù)when  
  37. Message prev = null 
  38. while (p != null && p.when <= when) {  
  39. prev = p;  
  40. p = p.next;  
  41.  
  42. msg.next = prev.next;  
  43. prev.next = msg;  
  44. this.notify(); // 喚醒  
  45.  
  46.  
  47. return true 

4 Java代碼

  1. public static final void loop() { 
  2. Looper me = myLooper(); 
  3. MessageQueue queue = me.mQueue; 
  4. while (true) { // 死循環(huán) 
  5. Message msg = queue.next(); // 當(dāng)隊列中沒有消息時會阻塞 
  6. if (msg != null) { 
  7. if (msg.target == null) { // 消息沒有發(fā)送者時,退出消息循環(huán) 
  8. // No target is a magic identifier for the quit message. 
  9. return
  10. if (me.mLogging!= null) me.mLogging.println( 
  11. ">>>>> Dispatching to " + msg.target + " " 
  12. + msg.callback + ": " + msg.what 
  13. ); 
  14. // 調(diào)用消息發(fā)出者的dispatchMessage,這里msg.target是我們sendMessage的handler 
  15. msg.target.dispatchMessage(msg); 
  16. if (me.mLogging!= null) me.mLogging.println( 
  17. "<<<<< Finished to " + msg.target + " " 
  18. + msg.callback); 
  19. msg.recycle(); 
  20. final Message next() { 
  21. boolean tryIdle = true
  22. while (true) { 
  23. synchronized (this) { 
  24. // 沒有消息的或,會阻塞 
  25. try { 
  26. if (mMessages != null) { 
  27. if (mMessages.when-now > 0) { 
  28. Binder.flushPendingCommands(); 
  29. this.wait(mMessages.when-now); 
  30. else { 
  31. Binder.flushPendingCommands(); 
  32. this.wait(); 
  33. catch (InterruptedException e) { 

總結(jié)

Handler作用:

1. 執(zhí)行計劃任務(wù)

2. 線程間通信

一個handler,只能接收到自己發(fā)出的message。handler實例與消息Message處理是關(guān)聯(lián)的,發(fā)送和接受要匹配

Handler操作隊列,主要是在子線程操作主線程的消息隊列

Handler是實現(xiàn)異步的一種方式,用法是在主線程中建立Handler,(主線程中的Handler不用掉Looper.prepare);

在子線程(耗時操作)任務(wù)完成后sendMessage,這個Message會發(fā)送到主線程的消息隊列中,主線程Handler的重寫dispatchMessage方法,做新線程任務(wù)完成后的事情,大部分是更新UI。

責(zé)任編輯:佚名 來源: Iteye
相關(guān)推薦

2016-10-21 13:03:18

androidhandlerlooper

2014-05-22 15:41:59

Android消息處理機制Looper

2014-05-22 15:38:27

Android消息處理機制Looper

2014-05-22 15:00:16

Android消息處理機制Looper

2014-05-22 15:04:00

Android消息處理機制Looper

2014-05-22 15:07:44

Android消息處理機制Looper

2014-05-22 15:48:50

Android消息處理機制Looper

2014-05-22 14:57:28

Android消息處理機制Looper

2014-05-22 15:15:53

Android消息處理機制Looper

2014-05-22 15:18:25

Android消息處理機制Looper

2014-05-22 15:33:31

Android消息處理機制Looper

2014-05-22 15:45:58

Android消息處理機制Looper

2013-03-28 16:12:12

Message機制應(yīng)用

2024-05-22 08:35:41

2012-12-28 14:32:34

Android開發(fā)Handler異步處理

2011-04-28 11:01:40

Android消息處理LooperHandler

2013-04-11 12:40:16

Android消息機制

2021-08-12 16:28:10

AndroidHandleLooper

2022-04-07 08:30:57

AMQP協(xié)議RabbitMQ客戶端源碼

2017-08-07 20:18:11

Android線程handler
點贊
收藏

51CTO技術(shù)棧公眾號