<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
    主站蜘蛛池模板: 激情亚洲一区国产精品| 久久久久久影院久久久久免费精品国产小说| 久久水蜜桃亚洲AV无码精品| 99re在线免费视频| 亚洲精品成人片在线播放| 亚洲精品又粗又大又爽A片| 99视频有精品视频免费观看| 最新国产精品亚洲| 蜜桃视频在线观看免费网址入口| 久久精品国产亚洲AV麻豆不卡| 一区二区三区AV高清免费波多| 日本免费一区尤物| 亚洲精品无码成人片久久不卡| 久久亚洲国产成人精品无码区| 亚洲AV成人片无码网站| 亚洲国产成人片在线观看无码| 日本视频在线观看永久免费| 老司机亚洲精品影视www| 免费黄色网址网站| 亚洲精品在线播放| 青青青国产在线观看免费网站| 亚洲精品伊人久久久久| 日韩一级免费视频| 99久在线国内在线播放免费观看 | 中国亚洲呦女专区| 美女的胸又黄又www网站免费| 最近中文字幕无吗免费高清| 亚洲色欲色欲www| 成人免费无遮挡无码黄漫视频| 国产真人无码作爱免费视频 | 亚洲成a人片在线观| 成年女人毛片免费播放视频m| a级毛片免费在线观看| 亚洲AV日韩AV永久无码色欲| 亚洲无成人网77777| 亚洲AV无码一区二区乱孑伦AS| 亚洲国产91精品无码专区| 99久久免费国产精精品| 免费一区二区无码视频在线播放| 久久亚洲精品视频| 亚洲人成无码久久电影网站|