Android中的Handler机制

在android主线程中做太耗时的操作会引起ANR崩溃,为了进行线程间通信,就需要用到handler消息处理机制。消息传递分为两类,一种是从MainThread向WorkerThread传递消息,而另外一种是从WorkerThread向MainThread传递消息。由于主线程主要负责UI相关的事件,如用户的点击事件,屏幕触摸事件等,当捕捉到用户动作后将会分发到相应的组件进行处理。因此,主线程也叫UI线程。

首先,我来说一下handler工作流程。还是用流程图的方式来表示,这样看起来一目了然。

handler(发送消息)➡MessageQueue(消息队列)➡Looper(取出消息)➡交给handler(调用handlerMessage方法去处理)➡更新UI界面

简单地总结一下,就是在子线程中通过handler去发送一条消息到主线程,这条消息就会进入到消息队列MessageQueue中,然后在主线程中调用Looper对象来管理消息队列,不断的从消息队列中取出消息,并将消息分给对应的Handler来处理,最后更新UI界面。

  • 从WorkThread向MainThread发送消息 
 1 package com.example.handlertest;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.os.Handler;
 6 import android.os.Message;
 7 import android.view.Menu;
 8 import android.view.View;
 9 import android.view.View.OnClickListener;
10 import android.widget.Button;
11 import android.widget.TextView;
12 
13 public class MainActivity extends Activity {
14     
15     private Button mybutton;
16     private TextView mytextview;
17     private Handler handler;
18     @Override
19     protected void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.activity_main);
22         mytextview=(TextView)findViewById(R.id.textview1);
23         mybutton=(Button)findViewById(R.id.button1);
24         mybutton.setOnClickListener(new ButtonListener());
25         handler=new firstHandler();
26     }
27     //不能直接在WorkerThread中去更新UI,所以使用handler来处理
28     class firstHandler extends Handler
29     {
30         @Override
31         public void handleMessage(Message msg) {
32             // TODO 在textview中显示获取到的数据
33             super.handleMessage(msg);
34             System.out.println("handlerMessage--->"+Thread.currentThread().getName());
35             String ss=(String)msg.obj;
36             mytextview.setText(ss);
37         }
38     }
39     class ButtonListener implements OnClickListener
40     {
41         @Override
42         public void onClick(View v) {
43             // TODO Auto-generated method stub
44             Thread td=new NetWorkThread();
45             td.start();
46         }
47     }
48     //开启一个子线程WorkerThread
49     class NetWorkThread extends Thread
50     {
51         @Override
52         public void run() {
53             // TODO 让线程休眠2s,利用handler向主线程发送消息
54             System.out.println("handlerMessage--->"+Thread.currentThread().getName());
55             super.run();
56             try
57             {
58                 Thread.sleep(1*1000);
59             }
60             catch(InterruptedException e)
61             {
62                 e.printStackTrace();
63             }
64             String s="全家福";
65             Message msg=handler.obtainMessage();
66             msg.obj=s;
67             handler.sendMessage(msg);
68         }
69     }
70 }
View Code
  •  从MainThread向WorkerThread发送消息
 1 package com.example.s2_e2;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.os.Handler;
 6 import android.os.Looper;
 7 import android.os.Message;
 8 import android.view.View;
 9 import android.view.View.OnClickListener;
10 import android.widget.Button;
11 import android.widget.TextView;
12 
13 public class MainActivity extends Activity {
14     
15     private Button button1;
16     private Handler handler;
17     @Override
18     protected void onCreate(Bundle savedInstanceState) {
19         super.onCreate(savedInstanceState);
20         setContentView(R.layout.activity_main);
21 
22         button1=(Button)findViewById(R.id.button1);
23         button1.setOnClickListener(new ButtonListener());
24         WorkerThread wd=new WorkerThread();
25         wd.start();
26     }
27     class ButtonListener implements OnClickListener
28     {
29 
30         @Override
31         public void onClick(View v) {
32             
33             System.out.println("clickThread is--->"+Thread.currentThread().getName());
34             Message msg=handler.obtainMessage();
35             handler.sendMessage(msg);
36         }
37         
38     }
39 
40     class WorkerThread extends Thread
41     {
42         @Override
43         public void run() {
44             //准备Looper对象
45             Looper.prepare();
46             //在WorkThread当中生成一个Handler对象
47             handler=new Handler(){
48                 @Override
49                 public void handleMessage(Message msg) {
50                     
51                     System.out.println("receive message--->"+Thread.currentThread().getName());
52                 }    
53             };
54             //Looper对象不断的从消息队列中取出消息对象,使用Handler的sendMessage来处理消息对象
55             //若没有消息则会发生阻塞
56             Looper.loop();
57         }
58         
59     }
60 }
View Code

另外,不得不提的是Handler的Post方法。

 1 package com.example.s2_e2;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.os.Handler;
 6 import android.os.Message;
 7 import android.view.View;
 8 import android.view.View.OnClickListener;
 9 import android.widget.Button;
10 import android.widget.TextView;
11 
12 public class MainActivity extends Activity {
13     
14     //问题1.如何把一个Runnable对象放置在消息队列中?
15     //问题2.Looper取出了带有r的Message对象之后,做了什么?
16     private Button button1;
17     Handler handler=new Handler();
18     @Override
19     protected void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.activity_main);
22 
23         button1=(Button)findViewById(R.id.button1);
24         button1.setOnClickListener(new ButtonListener());
25     }
26     class ButtonListener implements OnClickListener
27     {
28         @Override
29         public void onClick(View arg0) {
30             MyThread td=new MyThread();
31             td.start();
32         }
33     }
34     class MyThread extends Thread
35     {
36         @Override
37         public void run() {
38             Runnable r=new Runnable()
39              {
40                 @Override
41                 public void run() {
42                     //这里可以写更新UI的内容
43                     System.out.println("currentThread is"+MyThread.currentThread().getName());
44                 }
45              };
46         //1:该方法生成了一个Message对象,将r赋值给Message对象的callback属性,把Message对象放到消息队列中
47         //2:取出Message对象之后调用了dispatchMessage方法。由于callback不为空,所以执行了msg.callback方法
48              handler.post(r);
49         }
50     }
51 }

 

 

 

 

 

 

 

 

 

posted @ 2014-04-08 10:43  nick2681147  阅读(325)  评论(0编辑  收藏  举报