国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android 消息機制問題總結

2019-12-12 05:31:36
字體:
來源:轉載
供稿:網友

Android的消息機制幾乎是面試必問的話題,當然也并不是因為面試,而去學習,更重要的是它在Android的開發中是必不可少的,占著舉足輕重的地位,所以弄懂它是很有必要的。下面就來說說最基本的東西。

Looper

作用:

關聯起Thread

循環取出消息

1、Looper是否可以直接實例化?

Looper構造方法是私有的,其中做了兩件事

創建一個MessageQueue

得到與之對應的Thread

private Looper(boolean quitAllowed) {  mQueue = new MessageQueue(quitAllowed);  mThread = Thread.currentThread();}

2、一個線程能對應多個Lopper?

不能,一個線程對應一個Looper對象,通過ThreadLocal保證一個線程只有一個Looper與之對應,如果多次調用Looper.prepare();則會拋出運行時異常。

private static void prepare(boolean quitAllowed) {  if (sThreadLocal.get() != null) { // 查看是否有looper與當前線程對應    throw new RuntimeException("Only one Looper may be created per thread");  }  sThreadLocal.set(new Looper(quitAllowed));}

3、Looper是無限循環,會阻塞嗎?

是,當開啟一個loop后是一個死循環,從MessageQueue中取出消息,處理消息,但是也有可能退出,在沒有消息后退出循環。

public static void loop() {  final Looper me = myLooper();  if (me == null) {    throw new RuntimeException("No Looper; Looper.prepare() wasn't called on   this thread.");  }  final MessageQueue queue = me.mQueue; // 略  for (;;) {    Message msg = queue.next(); // might block    if (msg == null) { // 當沒有消息的時候,退出      // No message indicates that the message queue is quitting.      return;    }// 略    msg.target.dispatchMessage(msg);  }

4、可以再次調用Looper.prepareMainLooper嗎?

不可以,Looper.prepareMainLooper最終也是調用prepare(),同2.

public static void prepareMainLooper() {  prepare(false); // 創建一個Looper  synchronized (Looper.class) {    if (sMainLooper != null) {      throw new IllegalStateException("The main Looper has already been   prepared.");    }    sMainLooper = myLooper();  }}

5、MainLooper什么時候創建的?

MainLooper是啟動Activity創建ActivityThread(并不是一個Thread)時候創建,所以不能多次創建。

public static void main(String[] args) { // 略  Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); // 略 ActivityThread thread = new ActivityThread(); thread.attach(false); // 略 if (sMainThreadHandler == null) {  sMainThreadHandler = thread.getHandler(); } // 略 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }}

Handler

作用:

發送消息到MessageQueue

處理消息

1、Handler如何與Looper、MessageQueue關聯起來?

我們知道一個Looper對應一個Thread,一個Looper包含一個MessageQueue。當我們創建Handler時就會從當前線程中取出與之對應的Looper,讓后在從Looper中取出MessageQueue。

// 1、自動獲取public Handler(Callback callback, boolean async) { // 略  mLooper = Looper.myLooper(); // 取出當前線程中的Looper  if (mLooper == null) {    throw new RuntimeException(      "Can't create handler inside thread that has not called    Looper.prepare()");  }  mQueue = mLooper.mQueue; // 取出MessageQueue  mCallback = callback;  mAsynchronous = async;}// 2、傳遞一個Looper進來public Handler(Looper looper, Callback callback, boolean async) {    mLooper = looper;    mQueue = looper.mQueue;    mCallback = callback;    mAsynchronous = async;  }

Message

單項鏈表結構。

作用:

數據的載體

1、消息如何復用的?

從全局消息池(鏈表結構)中

public static Message obtain() {  synchronized (sPoolSync) {    if (sPool != null) {      Message m = sPool;      sPool = m.next;      m.next = null;      m.flags = 0; // clear in-use flag      sPoolSize--;      return m;    }  }  return new Message();}

2、Message為什么能傳遞?

Android中想要傳遞對象要么實現Serializable要么Parcelable,在這里是實現了Parcelable接口。

public final class Message implements Parcelable {
  // 略
}

3、如何與Handler關聯?

我們知道在消息傳機制中Handler充當著“快遞員”的角色,那么他又是如何與“貨物”--Message發生關系呢?實際上Message有一個成員變量target他的類型正是Handler,

/*package*/ Runnable callback;public int arg1; public int arg2;public Object obj;/*package*/ Handler target; // 關鍵點

當我們通過Handler去send一個Message時候最終都會為target賦值為this,即當前的Handler。

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {  msg.target = this; // 賦值語句  if (mAsynchronous) {    msg.setAsynchronous(true);  }  return queue.enqueueMessage(msg, uptimeMillis);}

另為如果是通過Message.Obtain(),獲取的復用Message也會為其賦值。

多說一句,Handler.obtainMessage()調用的就是Message.Obtain()。

public final Message obtainMessage(){  return Message.obtain(this);}

總結:

通過一系列的包涵關系,最終Looper、Handler、Message、MessageQueue即發生關聯,從而形成一個閉合,開啟消息循環。

困惑

最近一直在看這方面的知識,但是能力有限,還是有不少困惑,如果有錯誤,或你理解下面的問題請聯系我fvaryu@qq.com,愿與君交流學習,謝謝

1、Message中的sPool,哪里初始化的?為什么Message.obtain()中不會拋異常?

2、ActivityThread并不是線程,為什么可以創建一個Looper,Main Thread什么時候創建?

3、為什么序列化了的對象就可以傳遞?與Binder有關?

4、MessageQueue對應的是NativeMessageQueue,具體實現需要學習?

5、Loop.loop(),會退出嗎?退出時機是什么?如果會退出,那么主線程同樣會退出嗎?

以上就是對Android 消息機制的資料整理,后續繼續補充相關資料,謝謝大家對本站的支持

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 拉萨市| 新平| 贵南县| 谷城县| 峨边| 商洛市| 曲靖市| 汶川县| 广西| 琼结县| 延边| 淅川县| 福清市| 美姑县| 松原市| 孙吴县| 和静县| 绥棱县| 蓝山县| 康保县| 阜康市| 和顺县| 达州市| 五河县| 慈利县| 玛纳斯县| 睢宁县| 米易县| 泽普县| 嘉义县| 四子王旗| 威信县| 泰来县| 正定县| 辛集市| 义马市| 普洱| 吉木萨尔县| 天等县| 北京市| 明光市|