27
2017
09

Android 的消息机制(一)

Android 消息机制的概述

Android 的消息机制主要是指Handler的运行机制,Handler的运行需要底层MessageQueue和Lopper的支撑,MessageQueue的中文翻译是消息队列,顾名思义,他的内部储存了一组消息,以队列的形式对外提供插入和删除操作,,虽然叫消息队列,但是他的内部存储不是队列形式,而是采用单链表数据结构来储存消息列表,Looper的中文翻译为循环,,在这里可以理解为消息循环,由于MessageQueue只是一个消息储存单元,他不能处理消息,而Looper填补了这个功能,Looper会
无限循环的去查找是否有新的消息,如果有就去处理消息,否则就一直等待,Looper还有一个特殊概念,那就是ThreadLocal,ThreadLocal并不是一个线程,他的作用是在每个线程储存数据,我们知道,Handler创建的时候,会采用当前线程Looper来构建循环系统,那么Handler内部是如何获取到当前线程的Looper的,这就使用了ThreadLocal了,ThreadLocal可以在不同线程互不干扰的储存并提供数据,通过ThreadLocal可以轻松的获取每个线程的Looper,当然需要注意的是,线程默认是没有Loooper的,如果想要使用Looper,就必须为 线程创建Looper,我们经常提到主线程,也叫UI线程,他就是ActivityThread,他被创建时就会初始化Looper,这也是主线程默认可以使用Handler的原因

前面提到,Android 的消息机制主要是指Handler的运行机制,以及MessageQueue和Looper的工作过程,这三者实际上是一个整体,只是我们比较多的接触Handler,Handler主要将一个任务切换到在指定的线程,推出这个功能的主要原因,主线程不能做耗时任务,子线程无法访问UI的问题

为什么不允许在子线程访问UI

这是因为Android的UI控件不是线程安全的,如果在多线程并发访问UI可能导致,UI控件处于不可预期的状态,那么为什么不对,Ui控件加上锁呢,缺点有俩个,首先加上锁会让UI访问逻辑变得复杂,其次锁机制会降低UI访问效率,因为锁会阻塞线程的执行

如果在除了主线程外创建Handler需要自己创建Looper,代码如下

 Handler handler = new Handler(Looper.getMainLooper());

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

这里写图片描述

上一篇:Android 反编译Apk 下一篇:基于VerticalViewPager的上下滑动,可带动画效果,类似WheelView