最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android 消息隊(duì)列模型詳解及實(shí)例

 更新時(shí)間:2017年04月26日 10:58:10   投稿:lqh  
這篇文章主要介紹了 Android 消息隊(duì)列模型詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下

Android 消息隊(duì)列模型詳解及實(shí)例

Android系統(tǒng)的消息隊(duì)列和消息循環(huán)都是針對(duì)具體線程的,一個(gè)線程可以存在(當(dāng)然也可以不存在)一個(gè)消息隊(duì)列(Message Queue)和一個(gè)消息循環(huán)(Looper)。Android中除了UI線程(主線程),創(chuàng)建的工作線程默認(rèn)是沒(méi)有消息循環(huán)和消息隊(duì)列的。如果想讓該線程具有消息隊(duì)列和消息循環(huán),并具有消息處理機(jī)制,就需要在線程中首先調(diào)用Looper.prepare()來(lái)創(chuàng)建消息隊(duì)列,然后調(diào)用Looper.loop()進(jìn)入消息循環(huán)。如以下代碼所示:

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(); 
  } 
 } 

      這樣該線程就具有了消息處理機(jī)制了。如果不調(diào)用Looper.prepare()來(lái)創(chuàng)建消息隊(duì)列,會(huì)報(bào)"Java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()"的錯(cuò)誤。 

       通過(guò)下圖可以清晰顯示出UI Thread, Worker Thread, Handler, Massage Queue, Looper之間的關(guān)系:

 

       解釋上圖中的幾個(gè)基本概念: 

       1.Message

       消息對(duì)象,顧名思義就是記錄消息信息的類。這個(gè)類有幾個(gè)比較重要的字段:

       a.arg1和arg2:我們可以使用兩個(gè)字段用來(lái)存放我們需要傳遞的整型值,在Service中,我們可以用來(lái)存放Service的ID。
       b.obj:該字段是Object類型,我們可以讓該字段傳遞某個(gè)多項(xiàng)到消息的接受者中。
       c.what:這個(gè)字段可以說(shuō)是消息的標(biāo)志,在消息處理中,我們可以根據(jù)這個(gè)字段的不同的值進(jìn)行不同的處理,類似于我們?cè)谔幚鞡utton事件時(shí),通過(guò)switch(v.getId())判斷是點(diǎn)擊了哪個(gè)按鈕。

       在使用Message時(shí),我們可以通過(guò)new Message()創(chuàng)建一個(gè)Message實(shí)例,但是Android更推薦我們通過(guò)Message.obtain()或者Handler.obtainMessage()獲取Message對(duì)象。這并不一定是直接創(chuàng)建一個(gè)新的實(shí)例,而是先從消息池中看有沒(méi)有可用的Message實(shí)例,存在則直接取出并返回這個(gè)實(shí)例。反之如果消息池中沒(méi)有可用的Message實(shí)例,則根據(jù)給定的參數(shù)new一個(gè)新Message對(duì)象。通過(guò)分析源碼可得知,Android系統(tǒng)默認(rèn)情況下在消息池中實(shí)例化10個(gè)Message對(duì)象。 

       2.MessageQueue

       消息隊(duì)列,用來(lái)存放Message對(duì)象的數(shù)據(jù)結(jié)構(gòu),按照“先進(jìn)先出”的原則存放消息。存放并非實(shí)際意義的保存,而是將Message對(duì)象以鏈表的方式串聯(lián)起來(lái)的。MessageQueue對(duì)象不需要我們自己創(chuàng)建,而是有Looper對(duì)象對(duì)其進(jìn)行管理,一個(gè)線程最多只可以擁有一個(gè)MessageQueue。我們可以通過(guò)Looper.myQueue()獲取當(dāng)前線程中的MessageQueue。 

       3.Looper

       MessageQueue的管理者,在一個(gè)線程中,如果存在Looper對(duì)象,則必定存在MessageQueue對(duì)象,并且只存在一個(gè)Looper對(duì)象和一個(gè)MessageQueue對(duì)象。倘若我們的線程中存在Looper對(duì)象,則我們可以通過(guò)Looper.myLooper()獲取,此外我們還可以通過(guò)Looper.getMainLooper()獲取當(dāng)前應(yīng)用系統(tǒng)中主線程的Looper對(duì)象。在這個(gè)地方有一點(diǎn)需要注意,假如Looper對(duì)象位于應(yīng)用程序主線程中,則Looper.myLooper()和Looper.getMainLooper()獲取的是同一個(gè)對(duì)象。 

       4.Handler

       消息的處理者。通過(guò)Handler對(duì)象我們可以封裝Message對(duì)象,然后通過(guò)sendMessage(msg)把Message對(duì)象添加到MessageQueue中;當(dāng)MessageQueue循環(huán)到該Message時(shí),就會(huì)調(diào)用該Message對(duì)象對(duì)應(yīng)的handler對(duì)象的handleMessage()方法對(duì)其進(jìn)行處理。由于是在handleMessage()方法中處理消息,因此我們應(yīng)該編寫一個(gè)類繼承自Handler,然后在handleMessage()處理我們需要的操作。 

       另外,我們知道,Android UI操作并不是線程安全的,所以無(wú)法在子線程中更新UI。但Andriod提供了幾種方法,可以在子線程中通知UI線程更新界面: 

  1. Activity.runOnUiThread( Runnable )
  2. View.post( Runnable )
  3. View.postDelayed( Runnable, long )
  4. Handler

       比較常用的是通過(guò)Handler,用Handler來(lái)接收子線程發(fā)送的數(shù)據(jù),并用此數(shù)據(jù)配合主線程更新UI。那么,只要在主線程中創(chuàng)建Handler對(duì)象,在子線程中調(diào)用Handler的sendMessage方法,就會(huì)把消息放入主線程的消息隊(duì)列,并且將會(huì)在Handler主線程中調(diào)用該handler的handleMessage方法來(lái)處理消息。  

package com.superonion; 
 
import android.app.Activity; 
import android.os.Bundle; 
import android.os.Message; 
import android.util.Log; 
import android.os.Handler; 
 
public class MyHandler extends Activity { 
  static final String TAG = "Handler"; 
  Handler h = new Handler(){ 
    public void handleMessage (Message msg) 
    { 
      switch(msg.what) 
      { 
      case HANDLER_TEST: 
        Log.d(TAG, "The handler thread id = " + Thread.currentThread().getId() + "\n"); 
        break; 
      } 
    } 
  }; 
 
  static final int HANDLER_TEST = 1; 
  /** Called when the activity is first created. */ 
  @Override 
  public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Log.d(TAG, "The main thread id = " + Thread.currentThread().getId() + "\n"); 
 
    new myThread().start(); 
    setContentView(R.layout.main); 
  } 
 
  class myThread extends Thread 
  { 
    public void run() 
    { 
      Message msg = new Message(); 
      msg.what = HANDLER_TEST; 
      h.sendMessage(msg); 
      Log.d(TAG, "The worker thread id = " + Thread.currentThread().getId() + "\n"); 
    } 
  } 
} 
 

        以上代碼中,Handler在主線程中創(chuàng)建后,子線程通過(guò)sendMessage()方法就可以將消息發(fā)送到主線程中,并在handleMessage()方法中處理。

 感謝閱讀,希望能幫助大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

  • XRecyclerView實(shí)現(xiàn)下拉刷新、滾動(dòng)到底部加載更多等功能

    XRecyclerView實(shí)現(xiàn)下拉刷新、滾動(dòng)到底部加載更多等功能

    這篇文章主要為大家詳細(xì)介紹了XRecyclerView實(shí)現(xiàn)下拉刷新、滾動(dòng)到底部加載更多等功能,以及添加header功能的RecyclerView,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Kotlin?launch原理全面分析

    Kotlin?launch原理全面分析

    在Android開(kāi)發(fā)中,launch是我們經(jīng)常用的,今天來(lái)看看它是什么原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-11-11
  • android 仿微信demo——登錄功能實(shí)現(xiàn)(移動(dòng)端)

    android 仿微信demo——登錄功能實(shí)現(xiàn)(移動(dòng)端)

    本篇文章主要介紹了微信小程序-閱讀小程序?qū)嵗╠emo),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望能給你們提供幫助
    2021-06-06
  • 巧用ViewPager實(shí)現(xiàn)駕考寶典做題翻頁(yè)效果

    巧用ViewPager實(shí)現(xiàn)駕考寶典做題翻頁(yè)效果

    本文主要介紹巧用ViewPager實(shí)現(xiàn)駕考寶典做題翻頁(yè)效果的實(shí)例,具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-03-03
  • 詳解Android App卸載后跳轉(zhuǎn)到指定的反饋?lái)?yè)面的方法

    詳解Android App卸載后跳轉(zhuǎn)到指定的反饋?lái)?yè)面的方法

    這篇文章主要介紹了Android App卸載后跳轉(zhuǎn)到指定的反饋?lái)?yè)面的方法,關(guān)鍵點(diǎn)是相關(guān)線程要判斷在目錄被消除以前作出響應(yīng),需要的朋友可以參考下
    2016-04-04
  • Android ViewPager實(shí)現(xiàn)選項(xiàng)卡切換

    Android ViewPager實(shí)現(xiàn)選項(xiàng)卡切換

    這篇文章主要介紹了Android ViewPager實(shí)現(xiàn)選項(xiàng)卡切換,詳細(xì)分析了ViewPager實(shí)現(xiàn)選項(xiàng)卡切換功能,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Android 七種進(jìn)度條的樣式

    Android 七種進(jìn)度條的樣式

    在開(kāi)發(fā)中我們經(jīng)常要用到進(jìn)度條顯示下載或者加載的進(jìn)度。系統(tǒng)自帶的黃色進(jìn)度條在UI效果上經(jīng)常不能滿足策劃或者美工的要求。這就要我們屌絲程序員自己自定義進(jìn)度條,下面小編給大家介紹Android 七種進(jìn)度條的樣式,需要的朋友可以參考下
    2015-08-08
  • 淺談Viewpager和輪播圖的沖突解決方法

    淺談Viewpager和輪播圖的沖突解決方法

    下面小編就為大家?guī)?lái)一篇淺談Viewpager和輪播圖的沖突解決方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • Android控件之菜單的創(chuàng)建方式

    Android控件之菜單的創(chuàng)建方式

    本文給大家分享android控件菜單的兩種創(chuàng)建方式,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-09-09
  • android端實(shí)現(xiàn)驗(yàn)證碼隨機(jī)生成功能

    android端實(shí)現(xiàn)驗(yàn)證碼隨機(jī)生成功能

    這篇文章主要為大家詳細(xì)介紹了android端實(shí)現(xiàn)驗(yàn)證碼隨機(jī)生成功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07

最新評(píng)論

诸暨市| 拉孜县| 新竹县| 天水市| 晋城| 北安市| 大同县| 海城市| 杂多县| 墨玉县| 南投市| 苍南县| 舟曲县| 镇平县| 石泉县| 宁德市| 海原县| 磐安县| 获嘉县| 南阳市| 筠连县| 永福县| 仁化县| 郸城县| 公安县| 商丘市| 青岛市| 株洲市| 沂南县| 常山县| 门头沟区| 淳安县| 南陵县| 荥阳市| 大名县| 兴国县| 开化县| 同德县| 封丘县| 磐安县| 巫溪县|