欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android 消息機制問題總結

 更新時間:2016年08月26日 16:52:40   作者:fvaryu  
本文主要介紹Android 消息機制,這里整理了消息機制的詳細資料,和經常出現的問題,希望能幫助大家對消息機制的理解

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

Looper

作用:

關聯起Thread

循環(huán)取出消息

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

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

創(chuàng)建一個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) { // 查看是否有l(wèi)ooper與當前線程對應
    throw new RuntimeException("Only one Looper may be created per thread");
  }
  sThreadLocal.set(new Looper(quitAllowed));
}

3、Looper是無限循環(huán),會阻塞嗎?

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

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); // 創(chuàng)建一個Looper
  synchronized (Looper.class) {
    if (sMainLooper != null) {
      throw new IllegalStateException("The main Looper has already been   prepared.");
    }
    sMainLooper = myLooper();
  }
}

5、MainLooper什么時候創(chuàng)建的?

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

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

作用:

發(fā)送消息到MessageQueue

處理消息

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

我們知道一個Looper對應一個Thread,一個Looper包含一個MessageQueue。當我們創(chuàng)建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發(fā)生關系呢?實際上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即發(fā)生關聯,從而形成一個閉合,開啟消息循環(huán)。

困惑

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

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

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

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

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

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

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

相關文章

  • Framework源碼面試之activity啟動流程

    Framework源碼面試之activity啟動流程

    這篇文章主要為大家介紹了Framework源碼面試之activity啟動流程實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • ReactiveCocoa代碼實踐之-RAC網絡請求重構

    ReactiveCocoa代碼實踐之-RAC網絡請求重構

    這篇文章主要介紹了ReactiveCocoa代碼實踐之-RAC網絡請求重構 的相關資料,需要的朋友可以參考下
    2016-04-04
  • Android網絡通信的實現方式

    Android網絡通信的實現方式

    這篇文章主要為大家詳細介紹了Android網絡通信的實現方式,四種實現網絡通信的方式供大家學習,感興趣的小伙伴們可以參考一下
    2016-06-06
  • Android RecyclerView的Item自定義動畫及DefaultItemAnimator源碼分析

    Android RecyclerView的Item自定義動畫及DefaultItemAnimator源碼分析

    這篇文章主要介紹了Android RecyclerView的Item自定義動畫及DefaultItemAnimator源碼,感興趣的小伙伴們可以參考一下
    2016-07-07
  • 深入解析Android中的RecyclerView組件

    深入解析Android中的RecyclerView組件

    RecyclerView是Android 5.0以來新加入的組件,被廣泛認為是ListView的替代品,這里我們就結合理論與實踐來深入解析Android中的RecyclerView組件:
    2016-06-06
  • Flutter實現滾動選擇數字

    Flutter實現滾動選擇數字

    這篇文章主要為大家詳細介紹了Flutter實現滾動選擇數字,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 使用AccessibilityService實現微信自動切換賬號功能

    使用AccessibilityService實現微信自動切換賬號功能

    這篇文章主要為大家詳細介紹了使用AccessibilityService實現微信自動切換賬號功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • 基于將Android工程做成jar包和資源文件的解決方法

    基于將Android工程做成jar包和資源文件的解決方法

    有時候,我們希望將我們的Android工程提供給第三方開發(fā)者使用。這個時候,最普遍的做法,就是提供一個jar包和一堆資源文件,第三方開發(fā)者可以將資源文件拷貝到Android工程的相應目錄下,同時引用我們提供的jar包,就可以使用我們提供的相應API了
    2013-05-05
  • Android Listview點贊問題關于圖片重復問題

    Android Listview點贊問題關于圖片重復問題

    最近在開發(fā)android方面的項目時,遇到很多問題,下面小編以listview 與 baseadapter結合使用為例,給大家分享下關于點贊的的時候 圖片重復問題的解決方法,一起看看吧
    2016-11-11
  • Android內存泄漏的原因及解決技巧

    Android內存泄漏的原因及解決技巧

    這篇文章主要介紹了Android內存泄漏的原因及解決技巧,幫助大家更好的利用Android進行開發(fā),感興趣的朋友可以了解下
    2020-12-12

最新評論