Android系统中异步消息处理线程机制的理解
2015-10-29 17:14
369 查看
Android系统中异步消息处理线程机制的理解
普通线程:对于一般的线程模型,执行完run()方法内的代码后线程就结束了。
异步线程:线程启动后会进入一个无限的循环体之中,每次循环,从其内部的消息队列中取出一个消息,并回调相应的消息处理函数,执行完一个消息后继续循环。如果消息队列为空,线程会暂停,直到消息队列中有新的消息。
异步消息处理本质是仍然是一个线程,只不过这个线程的执行代码逻辑被设置成了异步线程模型所需要的。
异步线程的应用需求:
1)任务需要常驻。比如处理用户交互,网络请求处理等任务。
2)任务需要根据外部传递的消息做不同的操作。比如,根据不同消息,对不同任务的分发等
Android系统中的实现机制:
在android中实现异步线程主要涉及到如下几个类:ThreadLocal,Looper,MessageQueue,Handler,Message。
下面是网上的一张异步线程实现类的关系图:
ThreadLocal并不是Android的sdk中的类,而是java.lang中的一个类,该类的作用是为线程创建一个基于线程的变量存储,称之为线程局部存储。
简单的说,就是作用域在线程内,本线程内的该类的任何对象保持一致。
ThreadLocal可以使对象达到线程隔离的目的,它为每一个线程维护自己的变量拷贝,通过其中的set方法将变量绑定到线程上。ThreadLocal提供了一种解决多线程同步的问题解决方案,通过为每一份变量进行拷贝,这样的话,每个线程操作的都是属于自己的变量,而不是共同的一个变量,因此也就不需要同步锁了。在Android的异步线程中,ThreadLocal绑定的这个线程变量就是Looper的一个对象。
Looper类
Looper只是产生一个消息循环框架,首先Looper创建了消息队列(MessageQueue)并把它挂接在Linux的线程上下文中,进入到取消息,并分发消息的循环当中。
在Looper类中有一个成员变量mQueue(MessageQueue类的实例),该变量用于保存Looper中MessageQueue。 Looper通过静态方法Looper.prepare()方法来创建出一个MessageQueue对象。调用Looper类的
Handler类用来发送和处理消息(Message)以及和线程的消息队列(
外部系统需要向某个Android线程发送消息,必须通过属于该AndroidThread的Handler这个对象。每一个Handler对象都仅和一个线程及这个线程的消息队列关联。一个特定线程的所有Handler对象都会收到同样的方法。(这是一个“一对多”的关系)。如下图(图片来自网络)所示:
当你创建一个新的Handler对象,它会和创建它的这个线程/线程的消息队列绑定,从那个时刻开始,它将向这个消息队列传递消息和runnable对象,并且当它们从队列中出来时执行它们。
Handler主要有两种用途:
1.合理调度安排消息和runnable对象,使它们在将来的某个点被执行。
2.将一个动作入队安排在非当前线程执行。
Handler属于某个线程,取决Handlerd对象在哪个线程中建立。Handler在构建时做了如下的默认动作:
从线程上下文取得Looper。
通过Looper获取到消息队列并记录在自己的成员mQueue变量中
Handler使用消息队列进行对象封装,提供如下的成员函数:
通过 post(Runnable r)发送。Runnable是消息处理的回调函数,通过该消息的发送,引起Runable 的回调运行,post消息放置消息队列的前面。Message.callback=Runable.
通过 sendMessage发送。放置在所有的Post消息之后,sendMessage发送消息.
dispatchMessage分发消息。消息带有回调函数,则执行消息回调函数,如何没有则使用默认处理函数:handleMessage。而handleMessage往往被重载成某个继承
Handler对象的新的特定的handleMessage。几乎所有的Message发送时,都指定了target。Message.target=(this).
Handler对象的post方法和sendMessage方法本质上都是发送消息的方法(post类方法实质上是调用了sendMessage方法)。所谓发送消息就是把消息放入消息队列中的合适位置,并且把消息的target设置为本Handler对象。
所以当队列中的消息处理的时候,也会找到当时送它来的Handler对象,调用其相应的dispatchMessage()方法,进而调用其中的handleMessage()方法或者mCallback成员的handleMessage()方法来进行处理。
普通线程:对于一般的线程模型,执行完run()方法内的代码后线程就结束了。
异步线程:线程启动后会进入一个无限的循环体之中,每次循环,从其内部的消息队列中取出一个消息,并回调相应的消息处理函数,执行完一个消息后继续循环。如果消息队列为空,线程会暂停,直到消息队列中有新的消息。
异步消息处理本质是仍然是一个线程,只不过这个线程的执行代码逻辑被设置成了异步线程模型所需要的。
异步线程的应用需求:
1)任务需要常驻。比如处理用户交互,网络请求处理等任务。
2)任务需要根据外部传递的消息做不同的操作。比如,根据不同消息,对不同任务的分发等
Android系统中的实现机制:
在android中实现异步线程主要涉及到如下几个类:ThreadLocal,Looper,MessageQueue,Handler,Message。
下面是网上的一张异步线程实现类的关系图:
ThreadLocal
ThreadLocal并不是Android的sdk中的类,而是java.lang中的一个类,该类的作用是为线程创建一个基于线程的变量存储,称之为线程局部存储。简单的说,就是作用域在线程内,本线程内的该类的任何对象保持一致。
ThreadLocal可以使对象达到线程隔离的目的,它为每一个线程维护自己的变量拷贝,通过其中的set方法将变量绑定到线程上。ThreadLocal提供了一种解决多线程同步的问题解决方案,通过为每一份变量进行拷贝,这样的话,每个线程操作的都是属于自己的变量,而不是共同的一个变量,因此也就不需要同步锁了。在Android的异步线程中,ThreadLocal绑定的这个线程变量就是Looper的一个对象。
Looper类
Looper只是产生一个消息循环框架,首先Looper创建了消息队列(MessageQueue)并把它挂接在Linux的线程上下文中,进入到取消息,并分发消息的循环当中。
Looper类用来为一个线程跑一个消息循环。线程在默认情况下是没有消息循环与之关联的,Thread类在run()方法中的内容执行完之后就退出了,即线程做完自己的工作之后就结束了,没有循环的概念。
在Looper类中有一个成员变量mQueue(MessageQueue类的实例),该变量用于保存Looper中MessageQueue。 Looper通过静态方法Looper.prepare()方法来创建出一个MessageQueue对象。调用Looper类的
prepare()方法可以为当前线程创建一个消息循环,调用
loop()方法使之处理信息,直到循环结束。注意,Looper.prepare()方法在一个线程中只能执行一次。大多数和消息循环的交互是通过
Handler类进行的。
class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } }
Handler类
Handler类用来发送和处理消息(Message)以及和线程的消息队列(
MessageQueue)关联的Runnable对象。Handler对象在同一个线程上下文中取得消息队列,对消息队列进行封装操作,最主要的就是SendMessage和担当起dispatchMessage这个实际工作。
外部系统需要向某个Android线程发送消息,必须通过属于该AndroidThread的Handler这个对象。每一个Handler对象都仅和一个线程及这个线程的消息队列关联。一个特定线程的所有Handler对象都会收到同样的方法。(这是一个“一对多”的关系)。如下图(图片来自网络)所示:
当你创建一个新的Handler对象,它会和创建它的这个线程/线程的消息队列绑定,从那个时刻开始,它将向这个消息队列传递消息和runnable对象,并且当它们从队列中出来时执行它们。
Handler主要有两种用途:
1.合理调度安排消息和runnable对象,使它们在将来的某个点被执行。
2.将一个动作入队安排在非当前线程执行。
Handler属于某个线程,取决Handlerd对象在哪个线程中建立。Handler在构建时做了如下的默认动作:
从线程上下文取得Looper。
通过Looper获取到消息队列并记录在自己的成员mQueue变量中
Handler使用消息队列进行对象封装,提供如下的成员函数:
通过 post(Runnable r)发送。Runnable是消息处理的回调函数,通过该消息的发送,引起Runable 的回调运行,post消息放置消息队列的前面。Message.callback=Runable.
通过 sendMessage发送。放置在所有的Post消息之后,sendMessage发送消息.
dispatchMessage分发消息。消息带有回调函数,则执行消息回调函数,如何没有则使用默认处理函数:handleMessage。而handleMessage往往被重载成某个继承
Handler对象的新的特定的handleMessage。几乎所有的Message发送时,都指定了target。Message.target=(this).
Handler对象的post方法和sendMessage方法本质上都是发送消息的方法(post类方法实质上是调用了sendMessage方法)。所谓发送消息就是把消息放入消息队列中的合适位置,并且把消息的target设置为本Handler对象。
所以当队列中的消息处理的时候,也会找到当时送它来的Handler对象,调用其相应的dispatchMessage()方法,进而调用其中的handleMessage()方法或者mCallback成员的handleMessage()方法来进行处理。
相关文章推荐
- Android 广播大全
- android tv 开发的列表条目在获得焦点时的背景效果
- Android之打开闪光灯关键代码
- Android开发手记(17) 数据存储二 文件存储数据
- 换掉图片加载框架引发的血案 代理
- Android 百分比布局库(percent-support-lib) 解析与扩展
- Gradle 使用Gradle构建Android应用的渠道包
- Android签名
- android lint三部曲三:Android-Lint 检查问题列表
- Android 常见度量单位【xdpi、hdpi、mdpi、ldpi】 解读
- Android创建activity
- WebView的使用,android与JS混编
- android lint三部曲二:定制Android-Lint检查问题的现有规则
- android lint三部曲一:概述
- Android Lint 检查规则的定制(基本篇)
- java.lang.ClassCastException 在 android 当尝试获取应用程序的图标
- AndroidStudio之Gradle离线配置
- Android 底部导航菜单
- Android启动流程
- android lint简介