Android中的Handler机制

摘要:
在android主线程中做太耗时的操作会引起ANR崩溃,为了进行线程间通信,就需要用到handler消息处理机制。消息传递分为两类,一种是从MainThread向WorkerThread传递消息,而另外一种是从WorkerThread向MainThread传递消息。handlerMessageQueueLooper交给handler更新UI界面简单地总结一下,就是在子线程中通过handler去发送一条消息到主线程,这条消息就会进入到消息队列MessageQueue中,然后在主线程中调用Looper对象来管理消息队列,不断的从消息队列中取出消息,并将消息分给对应的Handler来处理,最后更新UI界面。

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

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

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

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

  • 从WorkThread向MainThread发送消息
Android中的Handler机制第1张Android中的Handler机制第2张
1 packagecom.example.handlertest;
2 
3 importandroid.app.Activity;
4 importandroid.os.Bundle;
5 importandroid.os.Handler;
6 importandroid.os.Message;
7 importandroid.view.Menu;
8 importandroid.view.View;
9 importandroid.view.View.OnClickListener;
10 importandroid.widget.Button;
11 importandroid.widget.TextView;
12 
13 public class MainActivity extendsActivity {
14     
15     privateButton mybutton;
16     privateTextView mytextview;
17     privateHandler handler;
18 @Override
19     protected voidonCreate(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(newButtonListener());
25         handler=newfirstHandler();
26 }
27     //不能直接在WorkerThread中去更新UI,所以使用handler来处理
28     class firstHandler extendsHandler
29 {
30 @Override
31         public voidhandleMessage(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 implementsOnClickListener
40 {
41 @Override
42         public voidonClick(View v) {
43             //TODO Auto-generated method stub
44             Thread td=newNetWorkThread();
45 td.start();
46 }
47 }
48     //开启一个子线程WorkerThread
49     class NetWorkThread extendsThread
50 {
51 @Override
52         public voidrun() {
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发送消息
Android中的Handler机制第3张Android中的Handler机制第4张
1 packagecom.example.s2_e2;
2 
3 importandroid.app.Activity;
4 importandroid.os.Bundle;
5 importandroid.os.Handler;
6 importandroid.os.Looper;
7 importandroid.os.Message;
8 importandroid.view.View;
9 importandroid.view.View.OnClickListener;
10 importandroid.widget.Button;
11 importandroid.widget.TextView;
12 
13 public class MainActivity extendsActivity {
14     
15     privateButton button1;
16     privateHandler handler;
17 @Override
18     protected voidonCreate(Bundle savedInstanceState) {
19         super.onCreate(savedInstanceState);
20 setContentView(R.layout.activity_main);
21 
22         button1=(Button)findViewById(R.id.button1);
23         button1.setOnClickListener(newButtonListener());
24         WorkerThread wd=newWorkerThread();
25 wd.start();
26 }
27     class ButtonListener implementsOnClickListener
28 {
29 
30 @Override
31         public voidonClick(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 extendsThread
41 {
42 @Override
43         public voidrun() {
44             //准备Looper对象
45 Looper.prepare();
46             //在WorkThread当中生成一个Handler对象
47             handler=newHandler(){
48 @Override
49                 public voidhandleMessage(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 packagecom.example.s2_e2;
2 
3 importandroid.app.Activity;
4 importandroid.os.Bundle;
5 importandroid.os.Handler;
6 importandroid.os.Message;
7 importandroid.view.View;
8 importandroid.view.View.OnClickListener;
9 importandroid.widget.Button;
10 importandroid.widget.TextView;
11 
12 public class MainActivity extendsActivity {
13     
14     //问题1.如何把一个Runnable对象放置在消息队列中?
15     //问题2.Looper取出了带有r的Message对象之后,做了什么?
16     privateButton button1;
17     Handler handler=newHandler();
18 @Override
19     protected voidonCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21 setContentView(R.layout.activity_main);
22 
23         button1=(Button)findViewById(R.id.button1);
24         button1.setOnClickListener(newButtonListener());
25 }
26     class ButtonListener implementsOnClickListener
27 {
28 @Override
29         public voidonClick(View arg0) {
30             MyThread td=newMyThread();
31 td.start();
32 }
33 }
34     class MyThread extendsThread
35 {
36 @Override
37         public voidrun() {
38             Runnable r=newRunnable()
39 {
40 @Override
41                 public voidrun() {
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 }

免责声明:文章转载自《Android中的Handler机制》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇OA发展史:由点到生态layer删除确认下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

深度分析WM_PAINT和WM_ERASEBKGND消息

       做windows开发这么久了,一直以来对WM_PAINT和WM_ERASEBKGND消息总是感觉理解的不准确,每次要自绘一个窗口都因为知其然不知其所以然,偶然发现一篇文章,详细透彻地分了这个两个消息的用途和设计初衷,这篇文章也是我见过最深入也是最准确关于WM_PAINT和WM_ERASEBKGND消息的,文中每一句话都值得咀嚼。先转载如下:...

Win32多线程编程(1) — 基础概念篇

  内核对象的基本概念 Windows系统是非开源的,它提供给我们的接口是用户模式的,即User-Mode API。当我们调用某个API时,需要从用户模式切换到内核模式的I/O System Services API。例如我们调用Kernel32.dll中的CreateFile创建文件,最终将执行ntdll.dll中的系统服务NtCreateFile...

微信定时获取token

为了使第三方开发者能够为用户提供更多更有价值的个性化服务,微信公众平台开放了许多接口,包括自定义菜单接口、客服接口、获取用户信息接口、用户分组接口、群发接口等,开发者在调用这些接口时,都需要传入一个相同的参数access_token,它是公众账号的全局唯一票据,它是接口访问凭证。 access_token的有效期是7200秒(两小时),在有效期内,可以一直...

委托和事件(C#)

基于事件驱动的程序设计是目前主流的程序设计方法,它是 Windows 应用程序设计和 Web 应用程序的基础。 完整的事件处理系统必须包含以下三大组成要素: (1)事件源:指能触发事件的对象,有时又称为事件的发送者或事件的发布者。 (2)侦听器:指能接收到事件事件消息的对象,Windows 提供了基础的事件侦听服务。 (3)事件处理程序:在事件发生时能对...

Linux 线程占用CPU过高定位分析

今天朋友问我一个Linux程序CPU占用涨停了,该如何分析, CPU占用过高,模拟CPU占用过高的情况 先上一段代码: 1 #include <iostream> 2 #include <thread> 3 #include <vector> 4 5 6 int main(int argc, char *...

mysql版本

MySQL 的官网下载地址:http://www.mysql.com/downloads/ linux下下载和安装: MySQL最新版本8.0.11(截止2018年六月份)for Linux下载 wget -P --no-check-certificate /usr https://dev.mysql.com/get/Downloads/MySQL-8....