浅谈android中Handler,Looper,Message

来源:互联网 发布:许昌市公务员网络培训 编辑:程序博客网 时间:2024/05/28 03:02
网上搜索后,在android中线程间通信使用Handler,Looper,Message这几个对象(不熟悉这些概念的同志们请自己查下)。

   这是网上的一个使用例子:

 

Java代码  收藏代码
  1. <span style="font-size: medium;">public class Activity2 extends Activity implements OnClickListener{  
  2.   
  3.        Button button = null;  
  4.   
  5.        TextView text = null;  
  6.   
  7.        MyHandler mHandler = null;  
  8.   
  9.        Thread thread ;  
  10.   
  11.        @Override  
  12.   
  13.        protected void onCreate(Bundle savedInstanceState) {  
  14.   
  15.               super.onCreate(savedInstanceState);  
  16.   
  17.               setContentView(R.layout.activity1);           
  18.   
  19.               button = (Button)findViewById(R.id.btn);  
  20.   
  21.               button.setOnClickListener(this);  
  22.   
  23.               text = (TextView)findViewById(R.id.content);  
  24.   
  25.        }  
  26.   
  27.        public void onClick(View v) {  
  28.   
  29.               switch (v.getId()) {  
  30.   
  31.               case R.id.btn:  
  32.   
  33.                      thread = new MyThread();  
  34.   
  35.                      thread.start();  
  36.   
  37.                      break;  
  38.   
  39.               }               
  40.   
  41.        }        
  42.   
  43.        private class MyHandler extends Handler{                
  44.   
  45.               public MyHandler(Looper looper){  
  46.   
  47.                      super(looper);  
  48.   
  49.               }  
  50.   
  51.               @Override  
  52.   
  53.               public void handleMessage(Message msg) {//处理消息  
  54.   
  55.                      text.setText(msg.obj.toString());  
  56.   
  57.               }               
  58.   
  59.        }  
  60.   
  61.        private class MyThread extends Thread{  
  62.   
  63.               @Override  
  64.   
  65.               public void run() {  
  66.   
  67.                      Looper curLooper = Looper.myLooper();  
  68.   
  69.                      Looper mainLooper = Looper.getMainLooper();  
  70.   
  71.                      String msg ;  
  72.   
  73.                      if(curLooper==null){  
  74.   
  75.                             mHandler = new MyHandler(mainLooper);  
  76.   
  77.                             msg = "curLooper is null";  
  78.   
  79.                      }else{  
  80.   
  81.                             mHandler = new MyHandler(curLooper);  
  82.   
  83.                             msg = "This is curLooper";  
  84.   
  85.                      }  
  86.   
  87.                      mHandler.removeMessages(0);  
  88.   
  89.                      Message m = mHandler.obtainMessage(111, msg);  
  90.   
  91.                      mHandler.sendMessage(m);  
  92.   
  93.               }               
  94.   
  95.        }  
  96.   
  97. }</span>  

 

 

这个没有问题,基本上三个对象的使用也很清楚,myHandler虽然是由子线程new出来的,但主线程持有引用,在我们的项目中不能用,因为我们几个线程属于不同的类,我尝试用下面的方法解决:

 

    在IoHandler中new一个android的handler,参数为主线程的Looper:

 

 

Java代码  收藏代码
  1. <span style="font-size: medium;">new Handler(Looper.getMainLooper()).sendMessage(msg);</span>  

IoHandler所在的线程给主线程发送消息(looper是主线程的,消息也就放在主线程的消息队列里了)

但是在主线程的handleMessage方法中得不到消息,尝试失败。

 

    那么怎么办呢,让IoHandler持有主线程的handler引用,具体做法有两种方式:

    1.  参数传递,把主线程的handler通过参数传递的形式传到IoHandler中。

    2. 静态变量,把主线程的handler申明为公共静态变量

 

Java代码  收藏代码
  1. <span style="font-size: medium;">public static Handler mainHandler;</span>  

 这样在Iohandler中使用

 

Java代码  收藏代码
  1. <span style="font-size: medium;">welcomeActivity.mainHandler.sendMessage(msg);</span>  

 这两种方式在主线程的 handleMessage的方法中都可以得到IoHandler发送的消息。

 本人使用的是静态变量解决的,因为有好几个来实现通信,参数传递太麻烦。

 

 那为什么我的第一种尝试是失败的呢,我是把消息放到主线程的消息队列了啊,这就要看android的一些实现机制了。

 通过网络和android的api,本人的理解如下:

 Looper是MessageQueue和Handler沟通的桥梁,Handler通过Looper把消息放入消息队列(MessageQueue),你想把消息发给谁,就把谁的looper作为参数传给Handler

 

Java代码  收藏代码
  1. <span style="font-size: medium;">newHandler(Looper looper);</span>  

  Looper把消息放入消息队列,并广播消息,这个不太好理解,我举例如下:

 

   主线程的Handler我们这样定义:Handler mainHandler = new Handler();  如果Handler没有参数,默认为当前线程的Looper

   子线程的Handler我们这样定义: Handler subHandler = newHandler(Looper.getMainLooper()); 参数为主线程的Looper

 这样两个线程都会把消息放入主线程的消息队列里了。

   现在mainHandler.sendMessage(), 消息进入主线程的消息队列,Looper广播消息,其实就是调用mainHandler的dispatchMessage方法,所有持有mianHandler引用的类都可以收到消息,注意啊,现在subHandler并不能接受到消息,因为Looper并没有调用subHandler的dispatchMessage方法,所以应该这样理解广播,A发送消息,那么A的Looper就调用A的dispatchMessage方法,别的B,C, D虽然也是A的Looper,但没有A的引用,所以B,C,D是接受不到消息的,如果B, C,D持有A的引用,但B,C,D不用A的Looper,那么也是接受不到消息的。这点在开发时要特别注意。


原创粉丝点击