一、为什么要用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机制的理解与使用相关推荐

  1. 自己写个C++版本Handler来理解Android的Handler机制

    由于日常工作不需要经常写android上层应用,对Android的Handler机制一直处于模模糊糊的状态.使用Handler之后,回去写c++代码时,时刻怀念Android里面的Handler,希望 ...

  2. 一分钟理解handler机制

    背景 小编昨晚跟同学聊了很久,了解到其面试中的困惑,每当被问handler机制时就不知道怎么去说,哪怕他知道handler的作用.在这里呢,小编就用案例的形式带你深入了解handler. 案例 异步加 ...

  3. android Handler机制之ThreadLocal详解

    概述 我们在谈Handler机制的时候,其实也就是谈Handler.Message.Looper.MessageQueue之间的关系,对于其工作原理我们不做详解(Handler机制详解). Messa ...

  4. Android多线程:深入分析 Handler机制源码(二)

    前言 在Android开发的多线程应用场景中,Handler机制十分常用 接下来,深入分析 Handler机制的源码,希望加深理解 目录 1. Handler 机制简介 定义 一套 Android 消 ...

  5. 深入浅出,Handler机制外科手术式的剖析(ThreadLocal,Looper,MessageQueen,Message)(上)...

    2019独角兽企业重金招聘Python工程师标准>>> 为什么会有handler机制? 在Android中,所有的UI控件都是运行在主线程中的, 如果我们从子线程访问UI,系统会报异 ...

  6. 浅谈Android中的Handler机制

    Handler是Android中提供的一种异步回调机制,也可以理解为线程间的消息机制.为了避免ANR,我们通常会把一些耗时操作(比如:网络请求.I/O操作.复杂计算等)放到子线程中去执行,而当子线程需 ...

  7. android binder与handler的简要理解

    android的进程之间的通信 采用binder机制,我们先弄明白binder到底是什么. 其实binder属于一个驱动,位于linux内核层,它的作用是完成进程间的通信. 而binder机制包括4个 ...

  8. 浅谈Handler机制

    Android中Handler是一个十分重要的东西,很多时候都需要用到Handler.那什么是Handler呢?又为什么要用Handler呢? 什么是Handler? 我们知道Android更新UI的 ...

  9. Handler 机制分析

    android 子线程和UI线程的交互主要使用Handler的方法进行通信.本文分析Handler机制 Handler 如何使用? Handler的使用比较简单 public class MainAc ...

  10. Android Handler机制

    1.什么是Handler?   Handler是可以通过发送和处理Message和Runnable对象来关联相应线程的MessageQueue.通常我们认为它是一种异步机制.   a.可以让对应的Me ...

最新文章

  1. ASP.NET MVC – 样式和布局简介
  2. MongoDb优化指南
  3. AI人必看!89页全网最全清华知识图谱报告
  4. linux命令怎么打开优盘,Linux下U盘使用具体步骤
  5. zabbix 监控mysql5.7_使用zabbix对mysql5.7主从进行监控
  6. C#反射——简单反射操作类的封装
  7. datastax.repo_使用Datastax Java驱动程序与Cassandra进行交互
  8. centos7升级openssh
  9. VR全景看年评!PConline年度评测盛典等你来体验
  10. 三角形状的点阵模糊效果iOS源码
  11. 联想计算机无线网络设置密码,联想(Lenovo)路由器怎么设置密码?
  12. Python(PyCharm)的下载安装汉化(2022)
  13. HTC G14解锁S OFF 刷机 获取ROOT权限
  14. java压缩图片thumbnails_Java压缩图片、减小图片文件体积大小,Thumbnails使用教程...
  15. 桌面计算机图标管理打不开怎么回事,电脑桌面计算机图标打不开怎么办
  16. python库吐血整理
  17. android网购功能,网购Android App购物车点击动画实现详解
  18. 学习笔记整理——vim,vim文件编码,vim配置文件
  19. 独立显卡安装ubuntu
  20. Element开发页面没有数据时,展示占位图片

热门文章

  1. freeswitch 录音录像模块和内核
  2. C++设计模式10--命令模式(二)(Command)--降低请求发送者与接收者耦合
  3. live555 RTSP服务器建立及消息处理流程
  4. 视频不显示的分析方法
  5. L2-010 排座位 (25 分)
  6. spark wordcount 实例
  7. 快排 递归与非递归实现 优化
  8. vs2013 .net连接mysql_Visual Studio C#.NET 轻松连接Mysql数据库之组件mysql-connector-net-网络教程与技术 -亦是美网络...
  9. 山石防火墙增加端口映射
  10. 计算机c盘是软盘吗,涨知识:为什么电脑都是从C盘开始,没有A和B?