`
xifangyuhui
  • 浏览: 185774 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

活用Android的Message Queue(1)

阅读更多

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 EventHandler(Looper.myLooper());可创建用来处理目前线程的Handler对象;其中,EventHandlerHandler的子类别。

l   使用mHandler = new EventHandler(Looper.getMainLooper());可创建用来处理main线程的Handler对象;其中,EventHandlerHandler的子类别。

 

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;

 

public class ac01 extends Activity implements OnClickListener {

    private final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;

    private final int FP = LinearLayout.LayoutParams.FILL_PARENT;

    public TextView tv;

    private EventHandler mHandler;

    private Button btnbtn2btn3;

   

    public void 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(FPWC);

        param2.topMargin = 10;

        layout.addView(tv, param2);

        setContentView(layout);     

    }

        public void 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

    public void 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;

 

public class ac01 extends Activity implements OnClickListener {

           private final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;

           private final int FP = LinearLayout.LayoutParams.FILL_PARENT;

           public TextView tv;

    private myThread t;

    private Button btnbtn2btn3;

   

    public void onCreate(Bundle icicle) {

                //文章长度有限,代码请参考上例

               }

              public void onClick(View v) {

                     switch(v.getId()){

                     case 101:

                       t = new myThread();

                       t.start();

                       break;

                     case 102:

                             finish();

                       break;

                     }

           }

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

class EHandler extends Handler {                                    //文章长度有限,代码请参考上例

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

class myThread extends Thread{

            private EHandler mHandler;

public void 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()函数来处理消息。此程序输出画面为:

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics