• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 深入理解Android消息處理系統——Looper、Handler、Thread

    發表于:2011-06-24來源:未知作者:娃娃點擊數: 標簽:Android
    熟悉Windows編程的朋友可能知道Windows程序是消息驅動的,并且有全局的消息循環系統。而Android應用程序也是消息驅動的,按道理來說也應該提供消息循環機制。實際上谷歌參考了Windows的消息循環機制,也在Android系統中實現了消息循環機制。Android通過Looper

      熟悉Windows編程的朋友可能知道Windows程序是消息驅動的,并且有全局的消息循環系統。而Android應用程序也是消息驅動的,按道理來說也應該提供消息循環機制。實際上谷歌參考了Windows的消息循環機制,也在Android系統中實現了消息循環機制。Android通過Looper、Handler來實現消息循環機制,Android消息循環是針對線程的(每個線程都可以有自己的消息隊列和消息循環)。本文深入介紹一下Android消息處理系統原理。

      Android系統中Looper負責管理線程的消息隊列和消息循環,具體實現請參考Looper的源碼。 可以通過Loop.myLooper()得到當前線程的Looper對象,通過Loop.getMainLooper()可以獲得當前進程的主線程的Looper對象。

      前面提到Android系統的消息隊列和消息循環都是針對具體線程的,一個線程可以存在(當然也可以不存在)一個消息隊列和一個消息循環(Looper),特定線程的消息只能分發給本線程,不能進行跨線程,跨進程通訊。但是創建的工作線程默認是沒有消息循環和消息隊列的,如果想讓該線程具有消息隊列和消息循環,需要在線程中首先調用Looper.prepare()來創建消息隊列,然后調用Looper.loop()進入消息循環。如下例所示:

      -----------------------------------------------------------------------

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

      }

      }

      ----------------------------------------------------------------------------------------------------

      這樣你的線程就具有了消息處理機制了,在Handler中進行消息處理。

      Activity是一個UI線程,運行于主線程中,Android系統在啟動的時候會為Activity創建一個消息隊列和消息循環(Looper)。詳細實現請參考ActivityThread.java文件。

      Handler的作用是把消息加入特定的(Looper)消息隊列中,并分發和處理該消息隊列中的消息。構造Handler的時候可以指定一個Looper對象,如果不指定則利用當前線程的Looper創建。詳細實現請參考Looper的源碼。

      Activity、Looper、Handler的關系如下圖所示:

      一個Activity中可以創建多個工作線程或者其他的組件,如果這些線程或者組件把他們的消息放入Activity的主線程消息隊列,那么該消息就會在主線程中處理了。因為主線程一般負責界面的更新操作,并且Android系統中的weget不是線程安全的,所以這種方式可以很好的實現Android界面更新。在Android系統中這種方式有著廣泛的運用。

      那么另外一個線程怎樣把消息放入主線程的消息隊列呢?答案是通過Handle對象,只要Handler對象以主線程的Looper創建,那么調用Handler的sendMessage等接口,將會把消息放入隊列都將是放入主線程的消息隊列。并且將會在Handler主線程中調用該handler的handleMessage接口來處理消息。

      這里面涉及到線程同步問題,請先參考如下例子來理解Handler對象的線程模型:

      1、首先創建MyHandler工程。

      2、在MyHandler.java中加入如下的代碼:

      package com.simon;

      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");

      }

      }

      }

      --------------------------------------------------------------------------------------------------------------------------

      在這個例子中我們主要是打印,這種處理機制各個模塊的所處的線程情況。如下是我的機器運行結果:

      09-10 23:40:51.478: DEBUG/Handler(302): The main thread id = 1

      09-10 23:40:51.569: DEBUG/Handler(302): The worker thread id = 8

      09-10 23:40:52.128: DEBUG/Handler(302): The handler thread id = 1

      我們可以看出消息處理是在主線程中處理的,在消息處理函數中可以安全的調用主線程中的任何資源,包括刷新界面。工作線程和主線程運行在不同的線程中,所以必須要注意這兩個線程間的競爭關系。

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>