<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-348  評論-598  文章-0  trackbacks-0
    public class

    Looper

    extends Object
    java.lang.Object
       ? android.os.Looper

    Class Overview

    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提供了一種消息循環機制,主要為Handler服務。
    你會問,在主線程里面可以創建Handler,那為什么還要啟動一個線程去Loop另外一個Handler呢?
    那是因為每個Handler實例只能服務于一個線程和他的消息隊列(Each Handler instance is associated with a single thread and that thread's message queue),如果你單獨啟動了另外一個線程去進行某些操作,同時又要發送消息,那么就需要你創建一個Looper線程,里面聲明一個Handler實例,然后在其他某個線程中去調用這個Handler,這樣就不會有問題了。
    當然這里需要注意的是,你不能在這個Handler中去修改UI控件的屬性,那是因為,你這個Handler仍然處于非UI主線程中,如果要修改UI,那么你可以在這個Handler中調用主線程的一個UI Handler去Post一個消息,在那個消息中對UI控件進行修改等操作。

    通過傳遞不同線程的Looper,可以使得Handler服務于不同的線程。

    1.  Message Queue的角色

    l   在你的Android程式裡,新誕生一個線程,或稱執行緒(Thread)時,並不會自動建立其Message Loop

    l   Android裡並沒有GlobalMessage Queue資料結構,例如,不同APK裡的物件不能透過Massage Queue來交換訊息(Message)

    l   一個線程可以誕生一個Looper之物件,由它來管理此線程裡的Message Queue

    l   你可以誕生Handler之物件來與Looper溝通,以便push新訊息到Message Queue裡;或者接收Looper(Message Queue取出)所送來的訊息。

    l   線程AHandler物件參考可以傳遞給別的線程,讓別的線程BC等能送訊息來給線程A(存於AMessage Queue)

    l   線程AMessage Queue裡的訊息,只有線程A所屬的物件可以處理之。

    l   使用Looper.myLooper可以取得目前線程的Looper物件參考值。

    l   使用mHandler = new EevntHandler(Looper.myLooper()); 可誕生用來處理目前線程的Handler物件;其中,EevntHandlerHandler的子類別。

    l   使用mHandler = new EevntHandler(Looper.getMainLooper()); 可誕生用來處理main線程的Handler物件;其中,EevntHandlerHandler的子類別。

    2. 範例之一:Looper物件之角色

    Looper類別用來管理特定線程內物件之間的訊息交換(Message Exchange)。你的應用程式可以誕生許多個線程,或稱執行緒(Thread)。而一個線程可以誕生許多個物件,這些物件之間常常需要互相交換訊息。如果有這種需要,您可以替線程誕生一個Looper類別之物件,來擔任訊息交換的管理工作。Looper物件會建立一個MessageQueue資料結構來存放各物件傳來的訊息(包括UI事件或System事件等)。如下圖:

         每一個線程(Thread,或稱「執行緒」)裡可含有一個Looper物件以及一個MessageQueue資料結構。在你的應用程式裡,可以定義Handler的子類別來接收Looper所送出的訊息。

    //----- Looper_01範例 -----

    package com.misoo.kx04;

    import android.app.Activity;

    import android.graphics.Color;

    import android.os.Bundle;

    import android.os.Handler;

    import android.os.Looper;

    import android.os.Message;

    import android.view.View;

    import android.view.View.OnClickListener;

    import android.widget.Button;

    import android.widget.LinearLayout;

    import android.widget.TextView;

    publicclass ac01 extends Activity implements OnClickListener {

               privatefinalintWC = LinearLayout.LayoutParams.WRAP_CONTENT;

               privatefinalintFP = LinearLayout.LayoutParams.FILL_PARENT;

               public TextView tv;

        private EventHandler mHandler;

        private Button btn, btn2, btn3;

       

        publicvoid onCreate(Bundle icicle) {

                    super.onCreate(icicle);

                    LinearLayout layout = new LinearLayout(this);

                    layout.setOrientation(LinearLayout.VERTICAL);

                                  

                    btn = new Button(this);

                    btn.setId(101);

                    btn.setBackgroundResource(R.drawable.heart);

                    btn.setText("test looper");

                    btn.setOnClickListener(this);

                    LinearLayout.LayoutParams param =

                        new LinearLayout.LayoutParams(100,50);

                    param.topMargin = 10;

                    layout.addView(btn, param);

                   

                    btn2 = new Button(this);

                    btn2.setId(102);

                    btn2.setBackgroundResource(R.drawable.ok_blue);

                    btn2.setText("exit");

                    btn2.setOnClickListener(this);

                    layout.addView(btn2, param);

                   

                    tv = new TextView(this);

                    tv.setTextColor(Color.WHITE);

                    tv.setText("");

                    LinearLayout.LayoutParams param2 =

                       new LinearLayout.LayoutParams(FP, WC);

                    param2.topMargin = 10;

                    layout.addView(tv, param2);

                    setContentView(layout);     

                   }

                  publicvoid onClick(View v) {

                         switch(v.getId()){

                         case 101:

                                    Looper looper;

                              looper = Looper.myLooper();

                              mHandler = new EventHandler(looper);

                              mHandler.removeMessages(0);

                              // 清除整個MessageQueue裡的事件,確保不會通知到別人

                              String obj = "This my message!";

                              Message m = mHandler.obtainMessage(1, 1, 1, obj);

                              // 組裝成一個Message物件

                              mHandler.sendMessage(m);

                              // Message物件送入MessageQueue

                       break;

                         case 102:

                      finish();

                                    break;

                         }

               }

    //------------------------------------------------------             

    class EventHandler extends Handler

                   {

                       public EventHandler(Looper looper) {

                           super(looper);

                       }

                       @Override

                       publicvoid handleMessage(Message msg) {

                          tv.setText((String)msg.obj);

                   }

               }

    }

    //-------------------------------------------------------

    說明:

        此程式啟動時,目前線程(即主線程, main thread)已誕生了一個Looper物件,並且有了一個MessageQueue資料結構。

        指令:looper = Looper.myLooper();

    就呼叫Looper類別的靜態myLooper()函數,以取得目前線程裡的Looper物件之參考值。

    指令:mHandler = new EventHandler(looper);

    誕生一個EventHandler之物件來與Looper溝通。Activity等物件可以藉由EventHandler物件來將訊息傳給Looper,然後放入MessageQueue裡;EventHandler物件也扮演Listener的角色,可接收Looper物件所送來的訊息。如下圖:

    指令:Message m = mHandler.obtainMessage(1, 1, 1, obj);

    先誕生一個Message物件,並將資料存入次物件裡。

    指令:mHandler.sendMessage(m);

    就透過mHandler物件而將訊息m傳給Looper,然後放入MessageQueue裡。

    此時,Looper物件看到MessageQueue裡有訊息m,就將它廣播出去,mHandler物件接到此訊息時,會呼叫其handleMessage()函數來處理之,於是輸出"This my message!"於畫面上,如下:

    3. 範例之二:由別的線程送訊息到主線程的Message Queue

    //----- Looper_02範例 -----

    package com.misoo.kx04;

    import android.app.Activity;

    import android.graphics.Color;

    import android.os.Bundle;

    import android.os.Handler;

    import android.os.Looper;

    import android.os.Message;

    import android.view.View;

    import android.view.View.OnClickListener;

    import android.widget.Button;

    import android.widget.LinearLayout;

    import android.widget.TextView;

    publicclass ac01 extends Activity implements OnClickListener {

               privatefinalintWC = LinearLayout.LayoutParams.WRAP_CONTENT;

               privatefinalintFP = LinearLayout.LayoutParams.FILL_PARENT;

               public TextView tv;

       private myThread t;

        private Button btn, btn2, btn3;

       

        publicvoid onCreate(Bundle icicle) {

                    super.onCreate(icicle);

                    LinearLayout layout = new LinearLayout(this);

                    layout.setOrientation(LinearLayout.VERTICAL);

                                  

                    btn = new Button(this);

                    btn.setId(101);

                    btn.setBackgroundResource(R.drawable.heart);

                    btn.setText("test looper");

                    btn.setOnClickListener(this);

                    LinearLayout.LayoutParams param =

                        new LinearLayout.LayoutParams(100,50);

                    param.topMargin = 10;

                    layout.addView(btn, param);

                   

                    btn2 = new Button(this);

                    btn2.setId(102);

                    btn2.setBackgroundResource(R.drawable.ok_blue);

                    btn2.setText("exit");

                    btn2.setOnClickListener(this);

                    layout.addView(btn2, param);

                   

                    tv = new TextView(this);

                    tv.setTextColor(Color.WHITE);

                    tv.setText("");

                    LinearLayout.LayoutParams param2 =

                       new LinearLayout.LayoutParams(FP, WC);

                    param2.topMargin = 10;

                    layout.addView(tv, param2);

                    setContentView(layout);     

                   }

                  publicvoid onClick(View v) {

                         switch(v.getId()){

                         case 101:

                                     t = new myThread();

                              t.start();

                              break;

                         case 102:

                      finish();

                                    break;

                         }

               }

    //------------------------------------------------------             

    class EHandler extends Handler {

                       public EHandler(Looper looper) {

                           super(looper);

                       }

                       @Override

                       publicvoid handleMessage(Message msg) {

                          tv.setText((String)msg.obj);

                   }

               }

    //------------------------------------------------------             

    class myThread extends Thread{

                private EHandler mHandler;

                publicvoid run() {

                    Looper myLooper, mainLooper;

                   myLooper = Looper.myLooper();

                    mainLooper = Looper.getMainLooper();

                    String obj;

                    if(myLooper == null){

                           mHandler = new EHandler(mainLooper);

                           obj = "current thread has no looper!";

                    }

                    else {

                         mHandler = new EHandler(myLooper);

                         obj = "This is from current thread.";

                    }

                    mHandler.removeMessages(0);

                    Message m = mHandler.obtainMessage(1, 1, 1, obj);

                    mHandler.sendMessage(m);

                }

     }

    }

    //-------------------------------------------------------

    Android會自動替主線程建立Message Queue。在這個子線程裡並沒有建立Message Queue。所以,myLooper值為null,而mainLooper則指向主線程裡的Looper物件。於是,執行到指令:

    mHandler = new EHandler(mainLooper); mHandler屬於主線程。

         指令:mHandler.sendMessage(m);

    就將m訊息存入到主線程的Message Queue裡。mainLooper看到Message Queue裡有訊息,就會處理之,於是由主線程執行到mHandlerhandleMessage()函數來處理訊息。此程式輸出畫面為:

    4. 結語:

    l   Message Loop的用途很廣。請你參閱高煥堂所寫的Android系列書籍,尤其是其中的第4本書:<<Android設計招式之美>>

    l   以上只是本文的前半段而已,請你繼續閱讀後半段。



    ---------------------------------------------------------
    專注移動開發

    Android, Windows Mobile, iPhone, J2ME, BlackBerry, Symbian
    posted on 2010-02-18 10:52 TiGERTiAN 閱讀(3537) 評論(0)  編輯  收藏 所屬分類: JavaAndroid
    主站蜘蛛池模板: 亚洲今日精彩视频| 免费播放一区二区三区| 亚洲嫩草影院在线观看| 国产亚洲精品资在线| 国产精品二区三区免费播放心| 日韩精品免费一级视频| 人人玩人人添人人澡免费| 一级人做人爰a全过程免费视频| 亚洲av日韩精品久久久久久a| 亚洲国产最大av| 亚洲第一页在线播放| 亚洲久本草在线中文字幕| 亚洲永久无码3D动漫一区| 亚洲人成电影网站国产精品| 国产男女猛烈无遮挡免费视频网站 | 亚洲kkk4444在线观看| 亚洲人成网站在线播放影院在线 | 七次郎成人免费线路视频| 精品国产日韩亚洲一区91| 亚洲一区二区三区高清在线观看 | 精品久久久久成人码免费动漫 | 亚洲最新视频在线观看| 亚洲成人动漫在线| 亚洲va久久久噜噜噜久久| 亚洲国产一成人久久精品| 亚洲人成亚洲人成在线观看 | 中文字幕免费在线播放| 国产精品黄页免费高清在线观看| 男人j进女人p免费视频| 无码的免费不卡毛片视频| 中美日韩在线网免费毛片视频| 九九久久精品国产免费看小说| 牛牛在线精品观看免费正 | 亚洲人成无码网WWW| 亚洲精品无码永久在线观看| 中文字幕专区在线亚洲| 久久精品国产亚洲5555| 亚洲综合色自拍一区| 亚洲国产精品一区二区第一页| 亚洲国产二区三区久久| 亚洲视频中文字幕在线|