Handler是在多线程之间使用的,用于线程之间进行通信。

要想知道为什么需要Handler就首先说明android的主线程和工作线程。
主线程又称为UI线程。正是因为在android中,所有与UI有关的操作(例如创建UI,刷新UI,处理UI等)都必须在主线程中进行,所以主线程又称为UI 线程。
如果当一个程序进行下载等操作的时候,需要的时间是非常长的,这时候如果主线程在执行下载量大的工作时,就会被阻塞在当前状态。此时,就会忽略用户操作,我给他称为假死机(个人理解)。这是如果用户的操作在5秒之内没有得到相应,android系统就会弹出一个对话框—程序无响应,强制关闭当前程序还是等待。这个叫ANR(android not responding)。
这种情况是android应用程序中非常避讳的。
要解决这种问题,就需要程序再创建一个子线程,即工作线程。让工作线程进行耗费大量时间的操作,而让主线程响应用户的操作。
也就是要做到不在主线程中执行可能导致阻塞的耗时代码而是把耗时代码在工作线程中执行。主线程只负责程序的调度和控制

为什么要使用Handler?

有人可能会问:创建一个工作线程太容易了,直接new Thread()不就可以了吗?然后把下载的工作全部放在工作线程中,当下载完成之后更新视图。
其实,这样做是行不通的,因为上边已经说到,android中关于UI的所有操作都必须放在主线程中进行操作。
所以正确的做法应该是:当我们需要下载一幅图片的时候,要创建一个工作线程进行下载,以便于主线程继续响应用户的操作。当工作线程将图片下载完成之后,我们需要工作线程通过一定的消息传递机制将下载的图片传递回UI线程,然后UI线程做显示图片的操作。
Handler,Looper,Message等一些类就凸显出他们的作用。
                              
 
通过上边的图,我们可以看到,在多线程处理中,在Handler,Message,Looper这三个类的处理中,可以组成一个闭合的环,这样我们就可以完成多线程的操作。

最简单的实现步骤是什么?

首先声明:以下步骤只是最简单的handler的使用步骤,如果想用更深入了解还得继续看下边的内容。
1、在主线程中创建一个Handler对象,并且覆写其handleMessage方法。
2、在创建的工作线程中创建一个Message消息对象,设置其响应的属性
3、使用此handler对象将这个Message发送到主线程的消息队列中。
4、主线程中的Looper对象会不断地监听消息队列中的内容,当监听到消息队列中有新的内容时,就会从消息队列中拿到此消息,并且交给发送这个消息的handler对象进行处理。
5、具体处理的方法则是调用第一步骤中的handleMessage方法中的内容
 
当看完以上的步骤,也许会有很多疑问,比如Looper是哪里来的?Message是什么?Message中都有哪些内容?
要想了解以上东西,继续往下看。

重点类的重点方法和属性有什么?Looper类

1、作用:
这个是用来封装消息循环和消息队列的一个类。上边的步骤已经说过,这个Looper类负责从消息队列中获取消息,并且执行handler的handleMessage方法。
其实当Looper获取到消息对象后,会进行一系列的判断。可能会执行不同的代码。执行handler的handleMessage方法只是其中的一种可能性。
具体要执行那个方法,我们待会再讲。
2、特性:
       只有在主线程中android系统才会默认的生成一个Looper对象。
       在工作线程中,如果不手动的建立一个Looper对象,默认是不存在Looper对象的。

Message类

1、作用:
         message,顾名思义,就是消息。也就是你要传递的数据的一种载体。例如,我想要发送一个标识符为1,传递一个int类型的数值4和一个代表音乐的music对象。那么我可以设置代表标识符的属性what的值为1,代表int类型的属性值为4,代表Object的属性值为music。
2、构造方法:Message()
3、实例化方法:
   obtain()     
此方法是首先从消息池中取得消息,如果消息池中的消息使用完再新建一个消息,这种方法比直接调用构造方法创建一个新的消息对象节省资源。
   obtain(Message msg)
   obtain(Handler target)
   obtain(Handler target,Runnable callback)
   obtain(Handler target,int what)
   obtain(Handler target,int what,Object obj)
   obtain(Handler target,int what,int arg1,intarg2)
   obtain(Handler target,int what,int arg1,intarg2,Object obj)
4、主要属性
   公共:
   intwhat   代表消息的标识符,用于唯一标识消息类型
   intarg1   可以用此属性传递一个int类型的数值
   int arg2      同arg1
   Object obj         可以用此属性传递一个Object类型的数值
  私有属性
   Handler target:该属性执行消息对象的发送者(handler)
   Runnable callback:
         当调用带有Runnable类型的构造方法创建消息的时候,当Looper对象从消息队列中拿出此消息时,会直接调用实现Runnable接口的对象的run()方法进行处理。而不是调用handler对象的handleMessage方法进行处理
5、主要方法:
   Runnable getCallback()
         获取实现Runnable接口的callback对象,注意这个callback属性没有setter方法,只有getter方法
   void setTarget(Handler target)
         设置目标handler,也就是说设置Looper对象获取这个消息后会交给哪个handler对象进行处理。
         注意,如果一个消息的目标handler为handler1,而实际发送这个消息的是handler2。
那么处理这个对象的handler是handler2,而不是handler1。因为在handler对象发送message的时候,会将发送此message的handler设为目标handler。
   Handler getTarget()
   void setData(Bundle data)
         在message中也可以直接传递Bundle对象,因为Bundle对象中装的都是键值对,这样这个消息就可以承载很多键值对了
   Bundle getData()
   void sendToTarget()
         将此消息发送给目标handler进行处理。也就是说当Looper从消息队列中获取此message后会交给目标handler处理。
         注意,此方法只有在调用setTarget()方法设置目标handler之后才能调用。否则只能使用handler.setMessage()方法发送消息。

Callback

boolean  handleMessage(Message msg)
callback接口中仅仅包含这一个抽象方法。
最值得注意的是,这个handleMessage方法的返回值是boolean类型的,而handler的handleMessage是void类型的。
 

Handler

1、构造方法:
   Handler()
   Handler(Looper looper) 创建一个Handler对象的时候指定一个Looper对象
   Handler(Callback callabck) 创建一个Handler对象的时候指定一个Callback对象
   Handler(Looper looper,Callback callback)
2、重要私有属性
   Looper looper
   Callback callback
3、主要方法:
   Looper getLooper()
         获取Looper对象。
         注意Looper对象没有setter方法。只能在调用构造方法的时候传递一个Looper对象
   boolean sendMessage(Message msg)
         发送一个message对象
   boolean sendMessageAtFrontOfQueue(Messagemsg)
         发送一个message对象,并且让此对象处于消息队列的头部,首先会被Looper对象拿走
   boolean sendMessageAtTime(Message msg,longtime)
         在一个时间点发送message对象
   boolean sendMessageDelayed(Message msg,longdelayMillis)
         延迟多长时间之后发送message消息
   boolean sendEmptyMessage(int what)
         发送一个只带有消息标识符的空消息
   boolean sendEmptyMessageAtTime(int what,longtime)
   boolean sendEmptyMessageDelayed(intwhat,long delayed)
   boolean post(Runnable callback)
         发送一个带有callback属性的消息
         这个方法的效果相当于
         Messagemessage  = Message. obtain(Handlertarget,Runnable callback)
         handler.sendMessage(message);
         上边的方法只是对以上两句代码的封装
         值得注意的是,并不是将一个实现Runnable接口的对象发送到消息队列,而是把一个封转好的消息发送到消息队列。我记得某个比较出名的视频里边就讲错了。特此更正一下。
   boolean postAtFrontOfQueue(Runnablecallback)
   boolean postAtTime(Runnable callback,longtime)
   boolean postDelayed(Runnable callback,longdelayed)
4、Handler的特性:
  1)Handler对象在创建时必须被关联到一个Looper(关联到消息队列)
    如果构造时未明确指定handler对象关联的Looper
    则默认关联到其创建时所在线程的Looper,如果该线程中不存在Looper
    则Handler创建失败
2)Handler对象,只能向其关联的消息队列发送消息
  3)消息处理原则:
     判断消息中是否包含Runnable对象(m.getCallback()!=null)
     如果消息中包含Runnable对象,则调用该对象的run方法,消息处理结束
     如果不包含Runnable对象,则进一步判断消息的发送者(m.getTarget())
     中是否包含callback对象(m.getTarget().getCallback()!=null)
       如果包含callback,则调用callback的handleMessage方法进行消息处理
         如果callback的handleMessage方法返回trueze消息处理结束
         否则,调用handler的handleMessage方法,消息处理结束
       如果不包含callback,则直接调用handler的handleMessage方法处理,消息
       处理结束

创建消息和发送消息一共有多少种方法?创建消息一共有三种方法:

1、  调用Message的构造方法
2、  调用Message的obtain()方法
3、  调用Handler对象的obtainMessage()的方法

发送消息一共有四种方法:

1、  调用Handler对象的sendMessage方法
2、  调用Handler对象的sendEmptyMessage方法
3、  调用Handler对象的Post方法
4、  调用Message对象的sendToTarget方法
 

消息处理的逻辑顺序是什么?

 
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

Handler知识点详解的更多相关文章

  1. Activity知识点详解

    Activity知识点详解 一.什么是Activity 官方解释: The Activity class is a crucial component of an Android app, and t ...

  2. python爬虫知识点详解

    python爬虫知识点总结(一)库的安装 python爬虫知识点总结(二)爬虫的基本原理 python爬虫知识点总结(三)urllib库详解 python爬虫知识点总结(四)Requests库的基本使 ...

  3. 「JVM」知识点详解一:JVM运行原理详解

    前言 JVM 一直都是面试的必考点,大家都知道,但是要把它搞清楚又好像不是特别容易.JVM 的知识点太散,不系统,今天带大家详细的了解一下jvm的运行原理. 正文 1 什么是JVM? JVM是Java ...

  4. OpenStack知识点详解

    一:云计算     一.起源 1. 云计算这个概念首次在2006年8月的搜索引擎会议上提出,成为了继互联网.计算机后信息时代的又一种革新(互联网第三次革命). 2. 云计算的核心是将资源协调在一起,使 ...

  5. Handler 使用详解

    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...

  6. android Handler机制详解

      简单运行图:    名词解析: Message(消息):定义了一个包含描述以及随意的数据对象可以被发送到Hanlder的消息,获得消息的最好方法是Message.obtain或者Handler.o ...

  7. ant+eclipse知识点详解及使用案例

    ant的优点和地位就不再阐述,下面直接上知识点: 在java中使用xml文件开发,有以下基本语法 (1)project:每个ant程序有且只有一个此标签,而且是类似于html的总标签,有name,de ...

  8. kafka知识点详解

    第一部分:kafka概述 一.定义(消息引擎系统) 一句话概括kafka的核心功能就是:高性能的消息发送与高性能的消息消费. kafka刚推出的时候是以消息引擎的身份出现的,它具有强大的消息传输效率和 ...

  9. 【Android】Android实现Handler异步详解

    方式不止一种,这里使用的是Timer类,创建一个定时器.我们经常需要获得移动设备端口的显示屏信息,但是onCreate()方法执行的时候,OnShow()方法不一定执行了,也就是说,在执行Oncrea ...

随机推荐

  1. [ios][swift]swift 怎么去除 optional

    在转换String时要使用“!”进行拆包,用“?”则会有optional 出现

  2. ACM题目————一笔画问题

    描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下来. 规定,所有的边都只能画一次,不能重复画. 输入 第一行只有一个正整数N(N< ...

  3. 20150626_Andriod_02_ListView2_列表与详细信息

    android listview 参考地址: http://www.cnblogs.com/zhengbeibei/archive/2013/05/14/3078805.html  http://xy ...

  4. Oracle连接字符串C#

    Password=密码;User ID=ID;Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = ...

  5. C语言typeof详解 offsetof

    http://blog.chinaunix.net/uid-28458801-id-4200573.html 前言:    typeof关键字是C语言中的一个新扩展,这个特性在linux内核中应用非常 ...

  6. Java中的类加载器

    转载:http://blog.csdn.net/zhangjg_blog/article/details/16102131 从java的动态性到类加载机制   我们知道,Java是一种动态语言.那么怎 ...

  7. C#中的字符串处理——找出最长数字子串

    百度测试部2015年10月份的面试题之——字符串处理,找出最长的子串. 代码如下: private static string SelectNumberFromString(string input) ...

  8. 2016CCPC东北地区大学生程序设计竞赛 1005 HDU5926

    链接http://acm.hdu.edu.cn/showproblem.php?pid=5926 题意:给我们一个矩阵,问你根据连连看的玩法可以消去其中的元素 解法:连连看怎么玩,就怎么写,别忘记边界 ...

  9. C++实现有向权图的基本操作,界面友好,操作方便,运行流畅

    Ⅰ.功能: .创建图 .展示全图 .添加顶点 .添加边 .删除顶点 .删除边 .查看指定边权值 .修改指定边权值 .输出两点间的所有简单路及路径对应权值 .销毁图 ps:关于9,如果不存在任何简单路, ...

  10. ubuntu中rar与unrar用法详解

    本文转载:http://helloklzs.iteye.com/blog/1139993 安装: sudo apt-get install rar 这样就可以安装了 删除是以下语句 sudo apt- ...