活用Android的Message Queue(2)

系统 1659 0

1.         复习 Message Queue 的角色

在上一篇里,介绍了 Android Thread Looper Message Queue Handler 四者间之关系。

先复习如下:

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

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

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

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

l     线程 A Message 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  btn btn2 ;

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

                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

活用Android的Message Queue(2)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论