2018-12-07 Handler机制


2018-12-07 Handler机制_第1张图片

简介

Handler用于线程间的通信,即异步消息的处理,比如子线程下载文件/图片,完成后通知主线程UI更改等等。handler用于发送消息和处理消息。当子线程的handler发送消息时,消息会被送往主线程的消息队列中(MessageQuene),等待Loop提取消息给主线程的Hanler处理。

为什么要设置通过Handler来更新UI,不用行吗?

android在设计的时候,就已经封装了一套完善的消息创建、传递、处理机制,如果不遵循这种机制就会抛异常。而设置这样机制最根本的问题是解决多线程并发带来的一些列问题。比如,一个UI中有多个线程同时对同一个控件进行更改样式的操作,那这个控件就会很混乱,无法控制。如果我们对所有更新UI的操作都做枷锁处理,其性能也会大打折扣。为了解决这样的问题,handler就诞生了,这使得我们在更新UI的时候不需要关心多线程问题。通常情况下,UI更新必须在主线程中进行的,当子线程需要更新UI时,就需要通过Handler发送消息到主线程的消息队列中排队等待处理。


子线程中更新UI的几种方式:  

一、使用runOnUiThread方式:

2018-12-07 Handler机制_第2张图片

二、通过Handler.sendMessage更新UI


2018-12-07 Handler机制_第3张图片


PS:为了避免内存泄露,在ondestroy的时候加下面这句:


2018-12-07 Handler机制_第4张图片


三、通过Handler.Post更改UI


2018-12-07 Handler机制_第5张图片

四、通过view.post更改UI


2018-12-07 Handler机制_第6张图片

子线程更改UI基本就是上面4中,看看Handler的工作原理

Handler原理

在说明原理前,我们需要了解他的成员以及作用

Handler:发送 / 处理  消息

Looper:消息封装的载体,类似于一个加工厂。

MessageQueue:存放众多消息,在Looper内部,类似于纽带。

Message:消息,类似于工作的物品。

handler首先发送消息到Looper工厂里面的纽带上,纽带很长,在工厂里面有一个抓手(Looper.Loop())这个抓手负责不断的从纽带上提取物品(message),当没有物品时,抓手就停止工作(阻塞),抓手抓到的东西在送往主线程的Handler去处理。

HandlerThread是什么

handlerThread会创建一个含有looper的handler,避免空指针异常。


在子线程创建Handler

在上面的代码中,handler都是在主线程创建的,下面试试在子线程创建hander,并让他往主线程发送消息。

首先创建MyThread线程

2018-12-07 Handler机制_第7张图片

我们在子线程穿件ThreadHandler,这是子线程的Handler,在run中让子线程发送消息,在子线程中处理,ThreadHandler的处理就是把消息发送给主线程的handler。让主线程去处理哈~下面的截图是主线程的handler。

2018-12-07 Handler机制_第8张图片
在主线程调用更改创建的子线程

子线程是一定不能更改UI吗?

其实不是的,子线程子所以不能改UI,是因为Android在线程的方法里面采用checkThread进行判断是否是主线程,而这个方法是在ViewRootImpl中的,这个类是在onResume里面才生成的,因此,如果这个时候子线程在onCreate方法里面生成更新UI,而且没有做阻塞,就是耗时多的操作,还是可以更新UI的。但是不推荐这么做!



参考:

Android-Handler机制详解

你可能感兴趣的:(2018-12-07 Handler机制)