活用Android的Message Queue(2)

1.       复习Message Queue的角色

在上一篇里,介绍了AndroidThreadLooperMessage QueueHandler四者间之关系。

先复习如下:

l   UI thread 通常就是main thread,而Android启动程序时(即创建Process)会替它建立一个Message Queue

l   当然需要一个Looper对象,来管理该Message Queue

l   我们可以创建Handler对象来push新消息到Message Queue里;或者接收Looper(Message Queue取出)所送来的消息。

l   线程AHandler对象引用可以传递给别的线程,让别的线程BC等能发送消息来给线程A(存于AMessage Queue)

l   线程AMessage Queue里的消息,只有线程A所属的对象可以处理之

 

 了解了四者间之关系后,在本篇里,就能来思考如何让主线程与子线程之间互相沟通了。包括,子线程push消息到主线程的Message Queue里,并触发主线程去执行某项工作(即执行某个函数)

 

2.  由别的线程发送消息到主线程的Message Queue()

    在上一篇文章里,使用如下程序片段:

// class ac01 extends Activity {

          // ………

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

                   public void handleMessage(Message msg) {

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

               }

           }

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

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

             }

  }

}

  

这个mHandler定义于myThread类别里,而且由子线程执行指令:      mHandler = new EHandler(mainLooper);

来创建EHandler对象;但是这个mHandler确是属于main线程的(用来存取主线程的MessageQueue),所以指令:

mHandler.sendMessage(m);是将m丢到主线程的MessageQueue里。

此外,我们也可以将mHandler定义于ac01类别里。如下程序范例:

 

//----- Looper_03范例 -----

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 btnbtn2;

    EventHandler h;

    Context ctx;

    public void onCreate(Bundle icicle) {

            super.onCreate(icicle);

            ctx = this;

                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:

             h = new EventHandler(Looper.myLooper());

             t = new myThread();

             t.start();

             break;

        case 102:

       finish();

            break;

        }

    }

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

public class EventHandler extends Handler {

            public EventHandler(Looper looper) {

                 super(looper);

             }

             @Override

             public void handleMessage(Message msg) {

                      ((Activity)ctx).setTitle((String)msg.obj);

             }

          }

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

class myThread extends Thread{

     public void run() {

            String obj = "from myThread";

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

            h.sendMessage(m);

      }

  }

}

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

 

指令:h = new EventHandler(Looper.myLooper());

h是属于main线程的(用来存取主线程的MessageQueue)。在myThread类别里的指令:h.sendMessage(m);

虽然是由子线程执行该指令,还是将m丢到主线程的MessageQueue里。于是,子线程所执行的run()函数,就顺利将m丢给主线程(Message Queue),并触发了主线程去执行handleMessage()函数了。显示出画面如下:

 

 

 1  

 

上述的指令:

 

          myLooper = Looper.myLooper();

          mainLooper = Looper.getMainLooper();

                ………

          mHandler = new EHandler(mainLooper);

                  ………

          mHandler = new EHandler(myLooper);

                    ………

 

明显地指明mHandler是负责存取哪一个线程的Message Queue。不过,有时候并不需要特别指明。例如上述的onClick()函数和EventHandler类别,可改写为:

 

//----- Looper_03aa 范例 -----

// class ac01 extends Activity {

          // ………

       public void onClick(View v) {

        switch(v.getId()){

        case 101:

             h = new EventHandler();

             t = new myThread();

             t.start();

             break;

        case 102:

              finish();

            break;

        }

    }

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

public class EventHandler extends Handler {

             @Override

             public void handleMessage(Message msg) {

                      ((Activity)ctx).setTitle((String)msg.obj);

             }

          }

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

class myThread extends Thread{

     public void run() {

            String obj = "from myThread";

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

            h.sendMessage(m);

      }

  }

}

 

指令:h = new EventHandler();  就等于:h = new EventHandler(Looper.myLooper());

它建立了当前线程(Current Thread)EventHandler对象。于此,是由main线程执行此指令的,所以此EventHandler对象是用来存取main线程的Message Queue

上述程序将handleMessage()定义于EventHandler类别内,也可以直接定义于ac01类别之内。于是上述程序,也相当于:

 

//----- Looper_03bb 范例 -----

// class ac01 extends Activity {

          // ………

          public void onClick(View v) {

        switch(v.getId()){

        case 101:

             h = new Handler(){

                 public void handleMessage(Message msg) {

                      ((Activity)ctx).setTitle((String)msg.obj);

             }};

              t = new myThread();

             t.start();

             break;

        case 102:

        finish();

            break;

        }

    }

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

class myThread extends Thread{

     public void run() {

            String obj = "from myThread...";

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

            h.sendMessage(m);

      }

  }

}

 

其执行结果是一样的。

 

转自:http://www.android1.net/Topic.aspx?BoardID=11&TopicID=631

你可能感兴趣的:(thread,android,UI,.net,FP)