Handler的定义:

主要接受子线程发送的数据, 并用此数据配合主线程更新UI.

解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进行事件分发, 比如说, 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。  如果此时需要一个耗时的操作,例如: 联网读取数据,    或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,,会收到Android系统的一个错误提示  "强制关闭".  这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,,Android主线程是线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的. 这个时候,Handler就出现了.,来解决这个复杂的问题 ,    由于Handler运行在主线程中(UI线程中),  它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据)  , 把这些消息放入主线程队列中,配合主线程进行更新UI。

Handler一些特点

handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程),
       它有两个作用: (1):  安排消息或Runnable 在某个主线程中某个地方执行, (2)安排一个动作在不同的线程中执行

Handler中分发消息的一些方法
       post(Runnable)
       postAtTime(Runnable,long)
       postDelayed(Runnable long)
       sendEmptyMessage(int)
       sendMessage(Message)
       sendMessageAtTime(Message,long)
       sendMessageDelayed(Message,long)

以上post类方法允许你排列一个Runnable对象到主线程队列中,
       sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新

使用Handler的大致流程:

1、首先创建一个Handler对象,可以直接使用Handler无参构造函数创建Handler对象,也可以继承Handler类,重写handleMessage方法来创建Handler对象。

2、在监听器中,调用Handler的post方法,将要执行的线程对象添加到线程队列当中。此时将会把该线程对象添加到handler对象的线程队列中。

3、将要执行的操作写在线程对象的run方法中,一般是一个Runnable对象,复写其中的run方法就可以了。

Handler包含了两个队列,其中一个是线程队列,另外一个是消息队列。使用post方法会将线程对象放到该handler的线程队列中,使用sendMessage(Messagemessage)将消息放到消息队列中。

  如果想要这个流程一直执行的话,可以在run方法内部执行postDelayed或者post方法,再将该线程对象添加到消息队列中,重复执行。想要线程停止执行,调用Handler对象的removeCallbacks(Runnable r) 方法从线程队列中移除线程对象,使线程停止执行。

Handler为Android提供了一种异步消息处理机制,当向消息队列中发送消息(sendMessage)后就立即返回,而从消息队列中读取消息时会阻塞,其中从消息队列中读取消息时会执行Handler中的public void handleMessage(Message msg) 方法,因此在创建Handler时应该使用匿名内部类重写该方法,在该方法中写上读取到消息后的操作,使用Handler的 obtainMessage() 来获得消息对象。

Handler与线程的关系:

  使用Handler的post方法将Runnable对象放到Handler的线程队列中后,该Runnable的执行其实并未单独开启线程,而是仍然在当前Activity线程中执行的,Handler只是调用了Runnable对象的run方法。

Bundle是什么:

Bundle是一个特殊的map,它是传递信息的工具,它的键只能是string类型,而且值也只能是常见的基本数据类型。

  如何让Handler执行Runnable时打开新的线程:

1、首先生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功能,这个类由Android应用程序框架提供

HandlerThread handlerThread = newHandlerThread("handler_thread");

2、在使用HandlerThread的getLooper()方法之前,必须先调用该类的start();

handlerThread.start();

3、根据这个HandlerThread对象得到其中的Looper对象。4、创建自定义的继承于Handler类的子类,其中实现一个参数为Looper对象的构造方法,方法内容调用父类的构造函数即可。

5、使用第三步得到的Looper对象创建自定义的Handler子类的对象,再将消息(Message)发送到该Handler的消息队列中,Handler复写的handleMessage()将会执行来处理消息队列中的消息。

  消息,即Message对象,可以传递一些信息,可以使用arg1.arg2,Object传递一些×××或者对象,还可以使用Message对象的 setData(Bundle bundle)来讲Bundle对象传递给新创建的线程,新创建的线程在执行handleMessage(Message msg)时可以从message中利用getData()提取出Bundle对象来进行处理。

public class HandlerTest2 extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {stubsuper.onCreate(savedInstanceState);setContentView(R.layout.main);//打印了当前线程的IDSystem.out.println("Activity-->" + Thread.currentThread().getId());//生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功能,这个类由Android应用程序框架提供HandlerThread handlerThread = new HandlerThread("handler_thread"); 11         //在使用HandlerThread的getLooper()方法之前,必须先调用该类的start();handlerThread.start();MyHandler myHandler = new MyHandler(handlerThread.getLooper());Message msg = myHandler.obtainMessage();//将msg发送到目标对象,所谓的目标对象,就是生成该msg对象的handler对象Bundle b = new Bundle(); 17         b.putInt("age", 20);b.putString("name", "Jhon");msg.setData(b);msg.sendToTarget();}class MyHandler extends Handler{public MyHandler(){}public MyHandler(Looper looper){super(looper); 29         }@Overridepublic void handleMessage(Message msg) {Bundle b = msg.getData();int age = b.getInt("age");String name = b.getString("name");System.out.println("age is " + age + ", name is" + name);System.out.println("Handler--->" + Thread.currentThread().getId());System.out.println("handlerMessage");}}}

转载于:https://blog.51cto.com/lzt1226/1277428

android之Handler详解相关推荐

  1. 【Android】Handler详解

    Handler的定义 主要接受子线程发送的数据, 并用此数据配合主线程更新UI. 解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进 ...

  2. Message,MessageQueue,Looper,Handler详解+实例

    Message,MessageQueue,Looper,Handler详解+实例 原文地址 Android的Handler使用(这篇简单介绍Handler的使用) 一.几个关键概念 1.Message ...

  3. Android SystemUI 架构详解

    Android SystemUI 架构详解 本文描述Android系统中一个核心应用SystemUI,详细赘述SystemUI中几大模块功能的实现过程.由于作者水平有限,如发现本文中错误的地方,欢迎指 ...

  4. Handler详解(中)

    Handler详解(上) https://blog.csdn.net/weixin_37730482/article/details/72864047 本章节讲解Handler的源码分析. 一.发送消 ...

  5. android组件模板,提高效率必备神器 ---- Android Studio模板详解

    原标题:提高效率必备神器 ---- Android Studio模板详解 Android Studio模板大家应该很熟悉,你新建一个project或者module的时候,AS会帮你提供几个选项供你选择 ...

  6. [Android]多进程知识点详解

    作者:Android开发_Hua 链接:https://www.jianshu.com/p/e0f833151f66 多进程知识点汇总: 一:了解多进程 二:项目中多进程的实现 三:多进程的优缺点与使 ...

  7. 《Android游戏开发详解》——第1章,第1.6节函数(在Java中称为“方法”更好)...

    本节书摘来自异步社区<Android游戏开发详解>一书中的第1章,第1.6节函数(在Java中称为"方法"更好),作者 [美]Jonathan S. Harbour,更 ...

  8. JMessage Android 端开发详解

    JMessage Android 端开发详解 目前越来越多的应用会需要集成即时通讯功能,这里就为大家详细讲一下如何通过集成 JMessage 来为你的 App 增加即时通讯功能. 首先,一个最基础的 ...

  9. 《Java和Android开发实战详解》——2.5节良好的Java程序代码编写风格

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第2章,第2.5节良好的Java程序代码编写风格,作者 陈会安,更多章节内容可以访问云栖社区"异步社区&quo ...

最新文章

  1. MySQL性能测试工具 mysqlslap
  2. 华南理工计算机基础知识题,华南理工_计算机应用基础_随堂练习答案(2017年)
  3. IO复用之epoll系列
  4. win mysql 最大连接_常用的三种修改mysql最大连接数的方法
  5. 熔断器 Hystrix 的原理与使用
  6. div css标记,前端初学者必学的div加css标签
  7. [css] 你是如何规划响应式布局的?
  8. 人口增量超过北上广!二线城市是怎样逆袭的?
  9. 软件测试的基础知识(五)
  10. 一点感想——还没学会跑,怎么能够想着飞
  11. 理解分布式和集群的区别
  12. 学习笔记--STM32F205+LCD
  13. 2022世界电信日|九州云携车路协同OpenV2X探索5G边缘计算新生态
  14. 如何申请电子邮箱,怎样注册163邮箱
  15. android-腾讯街景已经百度街景对比
  16. 风险预测模型_5分+整合多中心临床样本构建5分子胰腺癌预后模型
  17. 训练报错:RuntimeError: CUDA error: device-side assert triggered
  18. python find_peaks 源码理解
  19. 4大主流CPU处理器技术架构详解
  20. Linux使用带时区转换的时间函数注意事项(负负得正)

热门文章

  1. AI学会了视觉推理,“脑补”看不清的物体 | 李佳李飞飞等的CVPR论文
  2. linux 环境安装及学习
  3. Quick Switch Virtual Desktop[AutoHotkey]
  4. 计算机网络 - 物理层
  5. Java NIO和IO的主要区别
  6. 未来两年九大信息安全威胁
  7. 微信开发--开发模式简单配置
  8. 作用域闭包,你真的懂了吗?
  9. 也谈谈Javascript中的几个怪异特性(上)
  10. Android字数限制的EditText实现方案研究