多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當前位置:首頁 > php開源 > 綜合技術 > Android中異步消息處理機制

Android中異步消息處理機制

來源:程序員人生   發(fā)布時間:2015-04-03 08:33:23 閱讀次數(shù):2910次


1. Thread Local Storage (線程局部存儲)

     我們通過位于android.os包下的Looper.class源碼可以看到成員變量區(qū)有1個線程局部變量sThreadLocal,該類的作用是線程局部存儲?那末是線程局部存儲TLS?這個問題可以從變量作用域的角度來理解。
     
     變量的常見作用域1般包括以下幾種。
  • 函數(shù)內部變量。其作用區(qū)域是該函數(shù),即每次調用該函數(shù),該變量都會重新回到初始值。
  • 類內部的變量。其作用就是該類所產生的對象,即只要該對象沒有被燒毀,則對象內部的變量則1直保持。
  • 類內部的靜態(tài)變量。其作用是全部進程,即只要在該進程中,該變量的值就會1直保持,不管使用多少類來構造這個對象,該變量只有1個賦值,且1直保持。
對類內部的靜態(tài)變量而言,不管是從進程中那個線程援用該變量,其值總是相同的,由于編譯器內部為靜態(tài)變量分配了單獨的內存空間。但有時我們卻希望,當從同1個線程中援用該變量時,其值總是相同的, 而從不同的線程援用該變量,其值應當不同,即我們需要1種作用域為線程的變量定義,這就是線程局部存儲。

ThreadLocal內部實際上是使用弱援用WeakReference來存儲當前線程對象,但是不同的線程有不同的ThreadLocal對象,因此會有1個用于區(qū)分的id,由此內部封裝了1個靜態(tài)內部類Values,這個類就相當于1個map,存儲了每個線程的實例的值。

sThreadLocal在prepare()函數(shù)被調用的時候就進行了1次賦值,即構造1個新的Looper對象存儲到本地線程局部變量中,固然1個線程只能有1個Looper對象,否則會拋出以下圖所示的異常。

          

Looper中有2個用于構造Looper對象的方法。1個是prepare(),另外一個是prepareMainLooper()。
prepare()我們已說過了,下面說下prepareMainLooper()。
prepareMainLooper(),由方法注釋我們可以知道,這個利用程序的mainlooper對象是由android環(huán)境創(chuàng)建的,所以你自己永久沒必要調用這個函數(shù)。
               

2. Looper

我們可以從類注釋來了解Looper類的作用究竟是干甚么的。

Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare in the thread that is to run the loop, and then loop to have it process messages until the loop is stopped.

Most interaction with a message loop is through the Handler class.

This is a typical example of the implementation of a Looper thread, using the separation of prepare and loop to create an initial Handler to communicate with the Looper.

  class LooperThread extends Thread {
      public Handler mHandler;

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

          mHandler = new Handler() {
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };

          Looper.loop();
      }
  }
Looper類的作用就是給在線程內部創(chuàng)建1個消息循環(huán),固然線程本身內部是沒有1個消息循環(huán)機制;在run()函數(shù)首行調用Looper.prepare(),即便創(chuàng)建了1個消息循環(huán)隊列,然后在run函數(shù)尾行調用Looper.loop()則開始處理消息直到消息循環(huán)停止。
大多數(shù)消息循環(huán)的交互是通過Handler類進行的。


3. Handler

這里我們只從消息循環(huán)機制角度來分析這個Handler。首先看Handler的構造函數(shù)
/**
     * Default constructor associates this handler with the queue for the
     * current thread.
     *
     * If there isn't one, this handler won't be able to receive messages.
     */
    public Handler() {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }
         //從TLS(局部線程存儲)中取出已寄存好的Looper對象
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        //將Looper對象中的MessageQueue賦值給Handler中的對象
        mQueue = mLooper.mQueue;
        mCallback = null;
    }

然后我們在從使用的角度分析,這里我只從異步處理UI界面分析。
我們(程序員)通過 Handler調用sendMessage()函數(shù)在線程內部向UI主線程發(fā)送1個Message對象,該Message對象會順次通過Handler中的函數(shù)
sendMessage(...) -> sendMessageDelayed(...) -> sendMessageAtTime(...) 
終究會通過sendMessageAtTime發(fā)送消息對象。
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
    {
        boolean sent = false;
        MessageQueue queue = mQueue;
        if (queue != null) {
            msg.target = this;
       
            //將消息對象加入到消息隊列

            sent = queue.enqueueMessage(msg, uptimeMillis);
        }
        else {
            RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
        }
        return sent;
    }

然后我們在來看看enqueueMessage進行了甚么操作。

    final  boolean enqueueMessage(Message msg, long when) {
                      ...

        if (needWake) {
            nativeWake(mPtr);
        }

                      ...
   }

nativeWake是1個java本地方法,這里觸及了消息機制中的Sleep-Wakeup機制,關于如何喚醒Looper線程的動作,這里不做贅述,其終究就是調用了 native層的Looper的wake函數(shù),喚醒了這個函數(shù)以后,就開始進行消息循環(huán)
 

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 波多野结衣一区 | 亚洲欧美中文日韩综合 | 欧洲区二区三区四区 | 国产成人一区二区三区视频免费 | 最近手机中文字幕大全8 | 欧美日韩一区二区在线观看视频 | 国产麻豆免费观看 | 最近手机中文字幕高清1 | 久久久久久免费播放一级毛片 | 亚洲成人黄色在线 | 中文字幕校园春色 | 一区二区三区在线播放 | 在线观看美女网站 | 国产精品第一页在线观看 | 国产视频中文字幕 | 免费综合网 | 国产一区曰韩二区欧美三区 | 91福利国产在线观看香蕉 | 在线网| 亚欧美图片自偷自拍另类 | 欧美最猛黑人xxxx黑人猛交黄 | 国产高清毛片 | 亚洲国产精品a一区二区三区 | 国产中日韩一区二区三区 | 亚洲处破女网站 | 亚洲二区在线观看 | 亚洲精品嫩草研究院久久 | 欧美一级在线全免费 | 国产真实女人一级毛片 | 欧美日韩中文亚洲另类春色 | 亚洲欧洲无码一区二区三区 | 欧美日韩一区二区三区免费 | 欧美日韩亚洲国产一区二区综合 | 噜噜噜噜噜视频在线观看 | 午夜小影院 | 国产精品片 | a毛片免费播放全部完整 | 亚洲精品456在线播放 | 精品欧美成人高清在线观看2021 | 国语精品视频在线观看不卡 | 在线观看www成人影院 |