美文网首页
Android-消息处理机制Handler

Android-消息处理机制Handler

作者: 哎呦呦胖子斌 | 来源:发表于2018-06-15 13:00 被阅读0次

有的没的

        主线程:也叫UI线程,或称为Activity Thread,用于运行四大组件和处理与用户之间的交互,Activity Thread管理应用进程的主线程的执行,相当于普通java程序的main入口,在Activity系统中,在默认情况下,一个应用程序内的各个组件都会在同一个进程中执行,且由此进程的主线程负责执行。Activity Thread在处理不过来时可以创建多个子线程来处理后台服务工作,而本身专心处理UI画面的事件。

         子线程:用于执行耗时操作,比如I/O操作和网络请求等,更新UI的工作必须交给主线程,子线程是不允许更新UI的。

         消息机制:不同线程之间的通信,在Android中就是指Handler运行机制。消息机制是为了避免ANR(Application Not Responding),一旦发生ANR,程序就崩溃了。

以下两个条件任意一个触发的时候就会发生ANR:

① 在activity中超过5秒的时间未能相应下一个事件;

② BroadcastReceive超过10秒为响应

避免ANR

① 主线程不能执行耗时操作

② 子线程不能直接更新UI界面

        在Android的世界里,当子线程在执行耗时操作的时候,不是说主线程就阻塞在那里等待子线程的完成,也不是调用Thread.wait()或者是Thread.sleep(),android采取的是让主线程为子线程提供一个Handler,以便完成时能够提交给主线程。

为什么系统不允许子线程更新UI

         因为UI控件不是线程安全的,如果在多线程中并发访问可能会导致UI控件处于不可预期的状态,那为什么不对UI控件的访问加上上锁机制呢,原因有两个:

① 上锁会让UI控件变得复杂和低效;

② 上锁后会阻塞某些进程的执行。

        Handler的消息处理主要有五个部分组成,Message,Handler,Message Queue,Looper和ThreadLocal。

        Message:Message在线程之间传递消息,它可以在内部携带少量的数据,用于线程之间交换数据,它有四个常用的字段,what、arg1、arg2、obj,what、arg1、arg2可以携带整型数据,obj可以携带object对象。

        Handler:主要用于发送和处理消息,消息的发送一般使用sendMessage()方法,还有一系列的sendXXX方法,但最终都是为了调用sendMessageAtTime方法(除了sendMessageAtFrontOfQueue方法)。发出的消息经过一系列的处理后,最终会传递到Handler的handleMessage方法中。

        Message Queue:是指消息队列,主要用于存放所有通过Handler发送的消息,这部分消息会一直存在于消息队列中,等待被处理,每个线程中只会有一个MessageQueue对象。

        Looper:每个线程通过Handler发送的消息都保存在MessageQueue中,Looper通过调用loop()方法,就会进入到一个无限循环当中,每当发现MessageQueue中存在一条消息,就会将它取出,并传递到Handler的handleMessage方法中。每个线程只会有一个Looper对象。

        ThreadLocal:MessageQueue对象和Looper对象在每个线程中都只有一个,那么怎么保证他只有一个呢,就是通过ThreadLocal来保存。ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定的线程中可以获取到存储的数据,对于其他线程来说则无法获取到。

创建Handler

        每个程序都有一个入口,Android是基于java的,java程序的入口是静态的main函数,因此Android程序的入口也应该为静态的main函数,在Android程序中这个静态的main在ActivityThread类中,废话不多说,贴源码:

        在该方法中的红色框处,系统调用了Looper.prepareMainLooper()来创建主线程的Looper以及MessageQueue,并通过Looper.loop()来开启主线程的消息循环。看下这个方法的源码:

        首先在prepareMainLooper方法中调用了prepare()方法,在prepare()方法中先判断ThreadLocal中是否已经存在Looper对象了,以保证每个线程中只有一个Looper对象,再看Looper对象的创建,在其构造函数中创建出了一个MessageQueue对象并保存了当前线程。从上面的分析可以看出,一个线程只有一个Looper对象,而MessageQueue是在Looper构造函数中创建出来的,因此每一个线程也就只有一个MessageQueue对象。

         那么问题来了,为什么一定要新建Looper对象才能使用Handler呢,看Handler的构造函数:

        在红框处调用了myLooper()方法,看源码:

        这里就是获取ThreadLocal中是否含有Looper对象,明白啦,要使用Handler必须要有Looper对象才可以,Looper对象在哪建的还记得么,在Looper.prepare()方法中!经过上面这一通的分析想说明什么呢,就是在主线程中,系统通过调用prepareMainLooper()方法,已经为我们自动调用了Looper的prepare方法,也就是已经为我们新建好了Looper对象、ThreadLocal对象和MessageQueue对象,但在子线程中,就必须要主动调用Looper的prepare方法了。(没错这就是想要说明的结论!)

发送消息

        new一个Message对象,然后可以使用setData()方法或者arg参数等方式为消息携带一些数据,再借助Handler将消息发送出去就可以了(正好复习一下message发送与接收数据)。

        Handler中提供了很多个发送消息的方法,其中除了sendMessageAtFrontOfQueue()这个方法之外,其他的发送消息方法最终都会辗转调用到sendMessageAtTime()方法中,源码如下:

        sendMessageAtTime()方法将接收到的两个参数传递给MessageQueue的enqueueMessage()方法中,首先这两个参数是啥呢,msg就是我们发送的Message对象,uptimeMillis表示发送消息的时间,等于从系统开机到当前时间的毫秒数再加上延迟时间。MessageQueue是一个消息队列,用于将所有收到的消息以链表的形式进行排列,并提供消息入队和出队的方法,那么enqueueMessage()就是入队的方法了,看源码:

        从红框框出来的地方可以看到,所谓的入队就是将所有的消息按照时间来进行排序,如果使用的是sendMessageAtFrontOfQueue方法来发送消息就是将其时间设定为0,也就完成了添加消息到队列头部的操作。

接收消息

        在主线程中系统不仅帮我们自动调用了Looper.prepareMainLooper()方法,还帮我们调用了Looper.loop()方法,看下源码:

        从while(true)开始进入一个死循环,不断的调用MessageQueue的next()方法,这个next方法就是消息队列出队的方法,它的简单逻辑就是如果当前MessageQueue中存在待处理的消息mMessage,就将这个消息出队,然后让下一条消息成为mMessage,否则就进入一个阻塞状态,一直等到有新的消息入队。在loop()方法中,每当有一个消息出队,就将它传递到msg.target的dispatchMessage()方法中,这个msg.target就是Handler,看这个方法的源码:

        如果mCallback不为空,就调用mCallback的handleMessage方法,否则直接调用Handler的handleMessage方法,并将消息对象作为参数传递过去。所以当我们复用handleMessage方法的时候就可以从中获取到发送的消息了。整个过程如下:

相关文章

  • Android-消息处理机制Handler

    有的没的 主线程:也叫UI线程,或称为ActivityThread,用于运行四大组件和处理与用户之间的交互,A...

  • 安卓机制Handler

    Handler是什么? Handler是更新UI界面的机制,也是消息处理机制,我们可以发送消息,也可以处理消息 为...

  • Handler机制小结

    Handler笔记 什么是handler机制?handler机制的主要成员1、handler:负责发送处理消息2、...

  • Android面试必问handler机制浅析

    Handler机制 1、Handler是什么 Handler是Android中的异步消息处理机制。当发送一个消息之...

  • Handler

    1、handler是什么? handler是更新UI界面的机制,也是消息处理的机制,我们可以发送消息,也可以处理消...

  • Android消息机制解析

    Handler发送消息 Handler在消息机制中,起到发送和处理消息的作用。发送消息通过Handler.send...

  • android handler 机制 很简单

    1.android handler机制 handler机制,也就是android的异步消息处理机制。但是这个机制不...

  • 认识Handler消息机制

    什么是Handler消息机制? Handler是android提供用于更新UI的一套机制,也是消息处理机制。用于U...

  • Android-Handler机制详解

    Handler 1、handler是什么? handler是更新UI界面的机制,也是消息处理的机制,我们可以发送消...

  • Android-Handler机制详解

    1、handler是什么? handler是更新UI界面的机制,也是消息处理的机制,我们可以发送消息,也可...

网友评论

      本文标题:Android-消息处理机制Handler

      本文链接:https://www.haomeiwen.com/subject/pyzpeftx.html