Handler机制的理解与使用
一、为什么要用Handler
当应用程序启动时,会开启一个主线程(也就是UI线程),由她来管理UI,监听用户点击,来响应用户并分发事件等。所以一般在主线程中不要执行比较耗时的操作,如联网下载数据等,否则出现ANR(应用无响应)错误。所以就将这些操作放在子线程中,但是由于Android子线程是不安全的,所以只能在主线程中更新UI。Handler就是用来 子线程和创建Handler的线程进行通信的。
二、理解Handler机制的使用
开始今天的学习之前,我们先来了解一些概念:
Android是消息驱动的,实现消息驱动有几个要素:
消息的表示:Message
消息队列:MessageQueue
消息循环:用于循环取出消息进行处理:Looper
消息处理:消息循环从消息队列中取出消息后要对消息进行处理:Handler
handler类有两种主要用途:
1、按照时间计划,在未来某时刻,对处理一个消息或执行某个runnable实例。
2、把一个对另外线程对象的操作请求放入消息队列中,从而避免线程间冲突。
三、Handler机制的使用
Handler工具类在多线程中有两方面的应用:
1、发送消息,在不同的线程间发送消息,使用的方法为sendXXX();
android.os.Handler对象通过下面的方法发送消息的:
sendEmptyMessage(int),发送一个空的消息;
sendMessage(Message),发送消息,消息中可以携带参数;
sendMessageAtTime(Message, long),未来某一时间点发送消息;
sendMessageDelayed(Message, long),延时Nms发送消息。
2、计划任务,在未来执行某任务,使用的方法为postXXX();
android.os.Handler对象通过下面的方法执行计划任务:
post(Runnable),提交计划任务马上执行;
postAtTime(Runnable, long),提交计划任务在未来的时间点执行;
postDelayed(Runnable, long),提交计划任务延时Nms执行。
下面我们用代码来实现:
1、使用Message消息
public class HandlerActivity extends AppCompatActivity implements View.OnClickListener {TextView textHandler;Button buttonMessage, buttonRunnable;Handler handler;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_handler);textHandler = (TextView) findViewById(R.id.text_handler);buttonMessage = (Button) findViewById(R.id.button_message);buttonRunnable = (Button) findViewById(R.id.button_runnable);buttonMessage.setOnClickListener(this);buttonRunnable.setOnClickListener(this);handler = new MyHandler();}public class MyHandler extends Handler {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case 1:Log.e("测试", String.valueOf(msg.arg1 + msg.arg2));textHandler.setText(msg.obj.toString());break;}}}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button_message://使用Message的方式传递消息new Thread(new Runnable() {@Overridepublic void run() {Message message = handler.obtainMessage();message.arg1 = 1;message.arg2 = 2;message.obj = "小米";message.what = 1;message.sendToTarget();
// 也可以使用这种方式发送message
// handler.sendMessage(message);}}).start();break;case R.id.button_runnable://使用Runnable的方式传递消息new Thread(new Runnable() {@Overridepublic void run() {handler.post(new Runnable() {@Overridepublic void run() {//这句话其实是在创建handler的线程中执行的,这是则是在主线程中运行的//说明只是把runnable里的run方法放到UI线程里运行,并不会创建新线程//因此我们可以在子线程中将runnable加入到主线程的MessageQueue,然后主线程将调用runnable的方法,可以在此方法中更新主线程UI。textHandler.setText("小米2");}});}}).start();break;}}
}
2、使用Runnable传递
写在上面代码中!
四、在线程中创建Handler传递消息,还有HandlerThread的使用
如何在线程当中实例化Handler。在线程中实例化Handler我们需要保证线程当中包含Looper(注意:UI-Thread默认包含Looper)。
为线程创建Looper的方法如下:在线程run()方法当中先调用Looper.prepare()初始化Looper,然后再run()方法最后调用Looper.loop(),这样我们就在该线程当中创建好Looper。(注意:Looper.loop()方法默认是死循环)。
我们实现Looper有没有更加简单的方法呢?当然有,这就是我们的HandlerThread。我们来看下Android对HandlerThread的描述:
—Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.
Handler机制的分发中心就在Looper中的loop(),HandlerThread将loop转到子线程中处理,降低了主线程的压力,使主界面更流畅,其实 说白了,创建HandlerThread,只是为了用此线程的looper 最终的runnable都还是post到主线程运行(已用Toast测试过)
使用步骤
尽管HandlerThread的文档比较简单,但是它的使用并没有想象的那么easy。
1、创建一个HandlerThread,即创建了一个包含Looper的线程。
HandlerThread handlerThread = new HandlerThread(“HandlerThread”);
handlerThread.start(); //创建HandlerThread后一定要记得start()
2、获取HandlerThread的Looper
Looper looper = handlerThread.getLooper();
3、创建Handler,通过Looper初始化
Handler handler = new Handler(looper);
通过以上三步我们就成功创建HandlerThread。通过handler发送消息,就会在子线程中执行。
如果想让HandlerThread退出,则需要调用handlerThread.quit();
public class HandlerActivity extends AppCompatActivity implements View.OnClickListener {Button threadHandler, handlerThread;Handler threadHanlder;Handler hanlderThread;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_handler);threadHandler = (Button) findViewById(R.id.button_thread_handler);handlerThread = (Button) findViewById(R.id.button_handlerthread);threadHandler.setOnClickListener(this);handlerThread.setOnClickListener(this);//使用子线程中创建HandlerThreadHandler threadHandler = new ThreadHandler();threadHandler.start();//创建HandlerThreadHandlerThread handlerThread = new HandlerThread("hanlderThread");handlerThread.start();hanlderThread = new Handler(handlerThread.getLooper()) {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case 2:Log.e("HandlerThread", Thread.currentThread().toString());break;}}};Log.e("MianThread", Thread.currentThread().toString());}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button_thread_handler:threadHanlder.sendEmptyMessage(1);break;case R.id.button_handlerthread:hanlderThread.sendEmptyMessage(2);break;}}//使用子线程实现Hanlderpublic class ThreadHandler extends Thread {@Overridepublic void run() {super.run();Looper.prepare();threadHanlder = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case 1:Log.e("ThreadHandler", Thread.currentThread().toString());break;}}};Looper.loop();}}
}
布局:
Handler机制的理解与使用相关推荐
- 自己写个C++版本Handler来理解Android的Handler机制
由于日常工作不需要经常写android上层应用,对Android的Handler机制一直处于模模糊糊的状态.使用Handler之后,回去写c++代码时,时刻怀念Android里面的Handler,希望 ...
- 一分钟理解handler机制
背景 小编昨晚跟同学聊了很久,了解到其面试中的困惑,每当被问handler机制时就不知道怎么去说,哪怕他知道handler的作用.在这里呢,小编就用案例的形式带你深入了解handler. 案例 异步加 ...
- android Handler机制之ThreadLocal详解
概述 我们在谈Handler机制的时候,其实也就是谈Handler.Message.Looper.MessageQueue之间的关系,对于其工作原理我们不做详解(Handler机制详解). Messa ...
- Android多线程:深入分析 Handler机制源码(二)
前言 在Android开发的多线程应用场景中,Handler机制十分常用 接下来,深入分析 Handler机制的源码,希望加深理解 目录 1. Handler 机制简介 定义 一套 Android 消 ...
- 深入浅出,Handler机制外科手术式的剖析(ThreadLocal,Looper,MessageQueen,Message)(上)...
2019独角兽企业重金招聘Python工程师标准>>> 为什么会有handler机制? 在Android中,所有的UI控件都是运行在主线程中的, 如果我们从子线程访问UI,系统会报异 ...
- 浅谈Android中的Handler机制
Handler是Android中提供的一种异步回调机制,也可以理解为线程间的消息机制.为了避免ANR,我们通常会把一些耗时操作(比如:网络请求.I/O操作.复杂计算等)放到子线程中去执行,而当子线程需 ...
- android binder与handler的简要理解
android的进程之间的通信 采用binder机制,我们先弄明白binder到底是什么. 其实binder属于一个驱动,位于linux内核层,它的作用是完成进程间的通信. 而binder机制包括4个 ...
- 浅谈Handler机制
Android中Handler是一个十分重要的东西,很多时候都需要用到Handler.那什么是Handler呢?又为什么要用Handler呢? 什么是Handler? 我们知道Android更新UI的 ...
- Handler 机制分析
android 子线程和UI线程的交互主要使用Handler的方法进行通信.本文分析Handler机制 Handler 如何使用? Handler的使用比较简单 public class MainAc ...
- Android Handler机制
1.什么是Handler? Handler是可以通过发送和处理Message和Runnable对象来关联相应线程的MessageQueue.通常我们认为它是一种异步机制. a.可以让对应的Me ...
最新文章
- ASP.NET MVC – 样式和布局简介
- MongoDb优化指南
- AI人必看!89页全网最全清华知识图谱报告
- linux命令怎么打开优盘,Linux下U盘使用具体步骤
- zabbix 监控mysql5.7_使用zabbix对mysql5.7主从进行监控
- C#反射——简单反射操作类的封装
- datastax.repo_使用Datastax Java驱动程序与Cassandra进行交互
- centos7升级openssh
- VR全景看年评!PConline年度评测盛典等你来体验
- 三角形状的点阵模糊效果iOS源码
- 联想计算机无线网络设置密码,联想(Lenovo)路由器怎么设置密码?
- Python(PyCharm)的下载安装汉化(2022)
- HTC G14解锁S OFF 刷机 获取ROOT权限
- java压缩图片thumbnails_Java压缩图片、减小图片文件体积大小,Thumbnails使用教程...
- 桌面计算机图标管理打不开怎么回事,电脑桌面计算机图标打不开怎么办
- python库吐血整理
- android网购功能,网购Android App购物车点击动画实现详解
- 学习笔记整理——vim,vim文件编码,vim配置文件
- 独立显卡安装ubuntu
- Element开发页面没有数据时,展示占位图片
热门文章
- freeswitch 录音录像模块和内核
- C++设计模式10--命令模式(二)(Command)--降低请求发送者与接收者耦合
- live555 RTSP服务器建立及消息处理流程
- 视频不显示的分析方法
- L2-010 排座位 (25 分)
- spark wordcount 实例
- 快排 递归与非递归实现 优化
- vs2013 .net连接mysql_Visual Studio C#.NET 轻松连接Mysql数据库之组件mysql-connector-net-网络教程与技术
-亦是美网络...
- 山石防火墙增加端口映射
- 计算机c盘是软盘吗,涨知识:为什么电脑都是从C盘开始,没有A和B?