日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android的消息机制: Message/MessageQueue/Handler/Looper

發(fā)布時間:2025/4/5 Android 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android的消息机制: Message/MessageQueue/Handler/Looper 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
概覽 * Message:消息。消息里面可包含簡單數(shù)據(jù)、Object和Bundle,還可以包含一個Runnable(實際上可看做回調)。 * MessageQueue:消息隊列,供Looper線程消費消息。 * Looper:用于循環(huán)處理Message,一個Thread結合一個Looper來實現(xiàn)消息循環(huán)處理。Android App的主線程包含了Looper。 * Handler:負責向當前Looper線程發(fā)送Message,并實現(xiàn)如何處理消息的回調,回調可放到Callback接口的實現(xiàn)中,也可以放在傳遞進去的Runnable中的run中。 消息處理流程 1. MainThread(一個Looper Thread)正在運行,線程中有MessageQueue可交互,并循環(huán)處理MessageQueue中的Message。 2. 在MainThread中創(chuàng)建一個Handler,handler與當前線程Looper的MessageQueue綁定。 3. 通過handler.sendMessage(Message msg)向MessageQueue發(fā)送消息,等候執(zhí)行;通過handler.post(Runnable r)向MessageQueue發(fā)送一個空消息,該空消息附加了Runnable,等候執(zhí)行。 4. MainThread輪詢MessageQueue的Message,拋給Message對應的Handler執(zhí)行。
Message * 最好通過Message.obtain()來創(chuàng)建Message對象,從消息池里創(chuàng)建Message更高效。 源碼分析 public final class Message implements Parcelable { public int what; // 用戶定義的標識碼 public int arg1; // 用來存儲簡單的數(shù)據(jù),這樣可以不使用Object/Bundle來做消息。 public int arg2; public Object obj; // 對象型數(shù)據(jù)。 public Messenger replyTo;? Bundle data; // 復雜型消息數(shù)據(jù) // Message的最終處理分兩種情況: Handler target; // 1)通過Message的target(Handler)處理消息,具體是Handelr實現(xiàn)handleMessage()。 Runnable callback; // 2)通過空消息的callback(Runnable)處理消息,具體是丟棄Message,然后直接調用run()。 private static final Object sPoolSync = new Object(); // 消息池用到的鎖 private static Message sPool ; // 從消息池中取出的可用的消息對象。每取一次,這里就放置一個可用的。 private static int sPoolSize = 0; // 當前可用的消息對象數(shù)量 private static final int MAX_POOL_SIZE = 50 ; ?// 池存放最大量 Message next; // 實現(xiàn)鏈表式消息池 // 從消息池中取一個可用的消息對象 public static Message obtain() { synchronized (sPoolSync) { if (sPool != null) { Message m = sPool; sPool = m.next; m.next = null;? sPoolSize--; return m; } } return new Message(); } // 從現(xiàn)有Message復制并返回 public static Message obtain(Message orig) { Message m = obtain(); m.what = orig.what; m.arg1 = orig.arg1; m.arg2 = orig.arg2; m.obj = orig.obj; m.replyTo = orig.replyTo; if (orig.data != null) { m.data = new Bundle(orig.data); } m.target = orig.target; m.callback = orig.callback; return m; } // 發(fā)送消息? public void sendToTarget() { target.sendMessage(this); //?調用的是 handler 的 sendMessage() } // 消息回收 public void recycle() { clearForRecycle(); // 清除Message對象的所有信息 synchronized (sPoolSync) { if(sPoolSize < MAX_POOL_SIZE){ next = sPool; // 下一個可用Message是當前sPool(可用) sPool = this ; // 當前可用的Message為正在釋放清除的Message對象 sPoolSize++; // 可用對象數(shù)量遞增 } } } } MessageQueue *?holding the list of messages to be dispatched by a?Looper。 * 不能直接向Looper的MessageQueue添加Message,需要通過Handler。 * 可通過 Looper.myQueue()獲取到當前線程的MessageQueue。
Handler * 創(chuàng)建一個Handler就會綁定到當前Thread/MessageQueue,之后,Handler可以向MessageQueue發(fā)送Message和Runnable,等候輪詢執(zhí)行。 * 發(fā)送一個Message:sendMessage(Message m)。 * 發(fā)送一個Runnable:post(Runnable r) 。 public class Handler { // 自定義的Handler必須實現(xiàn)該方法,用于處理消息 public void?handleMessage(Message msg){} // 或者指定一個實現(xiàn)了Callback接口的類 public interface Callback { public boolean?handleMessage(Message msg); } // 構造函數(shù) // 默認情況下,handler會關聯(lián)到當前Thread的Looper,如果沒有Looper,拋異常 public Handler(Looper looper,Callback callback/*相當于指定了handleMessage()函數(shù)*/,boolean async){? mLooper=looper; mQueue=looper.mQueue; mCallback =callback;mAsynchronous = async; } public final Message obtainMessage(){ return Message.obtain(this); } // 直接調用的Message的obtain // --------------------------------------------------------------- //?發(fā)送消息到MessageQueue // handler.sendXXX均調用此方法 public boolean sendMessageAtTime(Message msg,long uptimeMillis) { MessageQueue queue = mQueue; return enqueueMessage(queue,msg,uptimeMillis); } private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) {msg.setAsynchronous(true);} return queue.enqueueMessage(msg, uptimeMillis); } //?--------------------------------------------------------------- //?發(fā)送Runnable到MessageQueue // 原理是把Runnable附加到一個空消息的callback上,當執(zhí)行消息時,如果發(fā)現(xiàn)有callback,則執(zhí)行callback。 public final boolean post(Runnable r) { return?sendMessageDelayed(getPostMessage(r),0); } private static getPostMessage(Runnable r,Object token) { Message m = Message.obtain(); m.obj = token; m.callback = r;?// 指定Message的callback為r。通過sendMessage的消息沒有callback,包含callback的Message將會被其callback執(zhí)行。 return m; } //?--------------------------------------------------------------- //?處理消息 // 消息在Looper中是通過調用這個函數(shù)來實現(xiàn)處理消息的 public void dispatchMessage(Message msg) { if(msg.callback!=null){?handleCallback(msg); } // 在Runnable中處理 else { handleMessage(msg); // 調用Handler處理消息的函數(shù) } } private static void?handleCallback(Message message) {? message.callback.run(); //消息被丟棄,并且直接調用run(),而不是新開線程。 } }// end handler()
Looper ? * 默認線程并沒有包含可以循環(huán)處理消息的功能,Looper類可以幫助線程實現(xiàn)消息循環(huán)。 ? public final class Looper { static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); // 線程本地變量,每個線程一個Looper。 final Message mQueue; final Thread mThread; private Looper(boolean quitAllowed){ mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); } // -------------------------------------------------------------------- // 準備。為當前線程創(chuàng)建一個Looper對象 static void prepare(boolean quitAllowed/*MessageQueue是否可退出*/) { if(sThreadLocal.get()!=null){/*Exception,當前線程的Looper已存在,一個線程一個Looper*/} sThreadLocal.set(new Looper(quitAllowed)); } // -------------------------------------------------------------------- // 開始循環(huán) public static void loop() { final Looper me = myLooper();// 當前線程的Looper實例 final MessageQueue queue = me.mQueue; for(;;){ Message msg = queue.next(); if(msg == null) {?return;} msg.target.dispatchMessage(msg); // 由Handler處理該消息 msg.recycle(); // 清理該消息,清空后返回消息池。 }//end for }// end loop() // -------------------------------------------------------------------- public void quit() { mQueue.quit(false); } public boolean isIdling(){ return mQueue.isIdling();} } // class end.
Demo

Demo#1 發(fā)送消息
class SomeActivity
{
  @Override
  public void onCreate(...){
  testMessage();
}

void testMessage(){
  MyHandler handler = new MyHandler();
  // or
  handler = new Handler(/*this.getMainLooper(),*/ new Handler.Callback(){ /*...*/ });

  // 發(fā)送Message
  Message m1 = new Message();
  m.setTarget(h);
  m.sendToTarget();

  // 發(fā)送Runnable(內部其實是發(fā)送了一個Message+Runnable)
  handler.post(new Runnable(){
    @Override
    public void run(){
      // 在主線程中運行
    }
  });
}

class MyHandler extends Handler{
  @Override
  public void handleMessage(Message msg){ /*...*/ }
}


Demo#2 自定義Looper線程
public static void testLooper()
{
  Thread tLooper = new Thread(new Runnable(){

  @Override
  public void run() {
    Looper.prepare();

    MyHandler h = new MyHandler();
    // 發(fā)送消息
    h.sendEmptyMessage(0);
    // 發(fā)送Runnable
    h.post(new Runnable(){
      @Override
      public void run() {
      Log.i("test","[in post runnable]threadid:"+Thread.currentThread().getId()); // tLooper線程ID
    }});

    Looper.loop(); // 一直循環(huán)。即使沒有消息
  }});
  tLooper.start();
}


references http://developer.android.com/reference/android/os/MessageQueue.html? http://developer.android.com/reference/android/os/Looper.html

總結

以上是生活随笔為你收集整理的Android的消息机制: Message/MessageQueue/Handler/Looper的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。