android_关于handler笔记

来源:互联网 发布:红蜘蛛软件怎么退出 编辑:程序博客网 时间:2024/04/25 08:13

Handler 学习笔记

Hnadler实例化过程需要注意的问题

到此先初步总结下上面关于Handler实例化的一些关键信息,具体如下:

1.在主线程中可以直接创建Handler对象,而在子线程中需要先调用Looper.prepare()才能创建Handler对象,否则运行抛出”Can’t create handler inside thread that has not called Looper.prepare()”异常信息。

2.每个线程中最多只能有一个Looper对象,否则抛出异常。

3.可以通过Looper.myLooper()获取当前线程的Looper实例,通过Looper.getMainLooper()获取主(UI)线程的Looper实例。

4.一个Looper只能对应了一个MessageQueue。

5.一个线程中只有一个Looper实例,一个MessageQueue实例,可以有多个Handler实例。

机制

Android的消息机制详解
Android的消息机制主要指 Handler 的运行机制,Handler的运行需要底层的MessageQueue 和 Looper 的支撑。

MessageQueue:消息队列,它的内部存储了一组消息,以队列的形式对外提供插入和删除的工作,其内部存储结构采用单链表的数据结构来存储消息列表。

Looper:可理解为消息循环。

由于MessageQueue只是一个消息存储单元,不能去处理消息,而Looper会以无限循环的形式去查找是否有新的消息,如果有的话就处理,否则就一直等待着。

Looper还有一个特殊的概念,就是ThreadLocal,它的作用可以在每个线程中存储数据。

Handler创建的时候会采用当前线程的Looper来构造消息循环系统,Handler内部需要使用ThreadLocal来获取每个线程的Looper。ThreadLocal可以在不同的线程中互不干扰地存储并提供数据。

注意:线程默认是没有Looper的,如果需要使用Handler就必须为线程创建Looper。主线程,UI线程,它就是ActivityThread,ActivityThread被创建时就会初始化Looper,这也是在主线程中默认可以使用Handler的原因。

Android消息机制概述
Android的UI控件不是线程安全的,如果在多线程中并发访问可能会导致UI控件处于不可预期的状态,如果对UI控件加锁会有两个确定:首先加上锁机制会使UI访问逻辑变得负责;其次锁机制会降低UI的访问效率,锁机制会阻碍某些线程的执行。鉴于这个两个缺点,最简单且高效的方法就是采用单线程模型来处理UI操作,只需要通过Handler切换一下UI访问的执行线程即可。

Handler创建完成后,其内部的 Looper 以及 MessageQueue就可以和Handler一起工作,Handler的post方法将一个 Runnable 投递到 Handler 内部的 Looper中去处理,也可以通过send发送一个消息(post最终也是通过send来完成的)。当Handler的send方法被调用时,它会调用 MessageQueue 的 enqueueMessage 方法将这个消息放入消息队列中,然后Looper发现有新消息到来时,就会处理这个消息,最终消息中的Runnable或者Handler的 handleMessage方法就会被调用。注意 Looper 是运行在创建Handler所在的线程中的,这样一来Handler中的业务逻辑就可以切换到创建Handler所在的线程中去执行。

0 0
原创粉丝点击