安卓处理机制

android的消息处理有三个核心类:Looper,Handler和Message。其实还有一个Message Queue(消息队列),但是MQ被封装到Looper里面了,我们不会直接与MQ打交道,因此我没将其作为核心类。下面一一介绍:

线程的魔法师 Looper

Looper的字面意思是“循环者”,它被设计用来使一个普通线程变成Looper线程。所谓Looper线程就是循环工作的线程。在程序开发中(尤其是GUI开发中),我们经常会需要一个线程不断循环,一旦有新任务则执行,执行完继续等待下一个任务,这就是Looper线程。使用Looper类创建Looper线程很简单:

通过上面两行核心代码,你的线程就升级为Looper线程了!!!是不是很神奇?让我们放慢镜头,看看这两行代码各自做了什么。

1)Looper.prepare()

通过上图可以看到,现在你的线程中有一个Looper对象,它的内部维护了一个消息队列MQ。注意,一个Thread只能有一个Looper对象,为什么呢?咱们来看源码。

通过源码,prepare()背后的工作方式一目了然,其核心就是将looper对象定义为ThreadLocal。如果你还不清楚什么是ThreadLocal,请参考《理解ThreadLocal》

2)Looper.loop()

调用loop方法后,Looper线程就开始真正工作了,它不断从自己的MQ中取出队头的消息(也叫任务)执行。其源码分析如下:

除了prepare()和loop()方法,Looper类还提供了一些有用的方法,比如

Looper.myLooper()得到当前线程looper对象:

getThread()得到looper对象所属线程:

quit()方法结束looper循环:

到此为止,你应该对Looper有了基本的了解,总结几点:

1.每个线程有且最多只能有一个Looper对象,它是一个ThreadLocal

2.Looper内部有一个消息队列,loop()方法调用后线程开始不断从队列中取出消息执行

3.Looper使一个线程变成Looper线程。

那么,我们如何往MQ上添加消息呢?下面有请Handler!(掌声~~~)

异步处理大师 Handler

什么是handler?handler扮演了往MQ上添加消息和处理消息的角色(只处理由自己发出的消息),即通知MQ它要执行一个任务(sendMessage),并在loop到自己的时候执行该任务(handleMessage),整个过程是异步的。handler创建时会关联一个looper,默认的构造方法将关联当前线程的looper,不过这也是可以set的。默认的构造方法:

下面我们就可以为之前的LooperThread类加入Handler:

加入handler后的效果如下图:

可以看到,一个线程可以有多个Handler,但是只能有一个Looper!

Handler发送消息

有了handler之后,我们就可以使用 post(Runnable), postAtTime(Runnable, long),
postDelayed(Runnable, long), sendEmptyMessage(int),
sendMessage(Message), sendMessageAtTime(Message, long)
sendMessageDelayed(Message, long)这些方法向MQ上发送消息了。光看这些API你可能会觉得handler能发两种消息,一种是Runnable对象,一种是message对象,这是直观的理解,但其实post发出的Runnable对象最后都被封装成message对象了,见源码:

其他方法就不罗列了,总之通过handler发出的message有如下特点:

1.message.target为该handler对象,这确保了looper执行到该message时能找到处理它的handler,即loop()方法中的关键代码

msg.target.dispatchMessage(msg);

2.post发出的message,其callback为Runnable对象

Handler处理消息

说完了消息的发送,再来看下handler如何处理消息。消息的处理是通过核心方法dispatchMessage(Message msg)与钩子方法handleMessage(Message msg)完成的,见源码

可以看到,除了handleMessage(Message msg)和Runnable对象的run方法由开发者实现外(实现具体逻辑),handler的内部工作机制对开发者是透明的。这正是handler API设计的精妙之处!

Handler的用处

我在小标题中将handler描述为“异步处理大师”,这归功于Handler拥有下面两个重要的特点:

1.handler可以在任意线程发送消息,这些消息会被添加到关联的MQ上。

2.handler是在它关联的looper线程中处理消息的。

这就解决了android最经典的不能在其他非主线程中更新UI的问题。android的主线程也是一个looper线程(looper 在android中运用很广),我们在其中创建的handler默认将关联主线程MQ。因此,利用handler的一个solution就是在 activity中创建handler并将其引用传递给worker thread,worker thread执行完任务后使用handler发送消息通知activity更新UI。(过程如图)

下面给出sample代码,仅供参考:

当然,handler能做的远远不仅如此,由于它能post Runnable对象,它还能与Looper配合实现经典的Pipeline Thread(流水线线程)模式。请参考此文《Android Guts: Intro to Loopers and Handlers》

封装任务 Message

在整个消息处理机制中,message又叫task,封装了任务携带的信息和处理该任务的handler。message的用法比较简单,这里不做总结了。但是有这么几点需要注意(待补充):

1.尽管Message有public的默认构造方法,但是你应该通过Message.obtain()来从消息池中获得空消息对象,以节省资源。

2.如果你的message只需要携带简单的int信息,请优先使用Message.arg1和Message.arg2来传递信息,这比用Bundle更省内存

3.擅用message.what来标识信息,以便用不同方式处理message。

本为来自http://www.cnblogs.com/codingmyworld/archive/2011/09/12/2174255.html  感谢每一个辛苦付出的人。

时间: 2024-10-06 09:18:38

安卓处理机制的相关文章

安卓运行机制JNI、Dalvik、ART之间的比较 。android L 修改运行机制。

Android L默认采用ART运行环境,完全兼容64位移动处理器.Google称这将比此前的Dalvik模式性能提高两倍,但是会占用更多的内存空间.Android有三种运行模式:JNI.Dalvik.ART.Dalvik明显是最慢的,完全的JNI模式是最快的但是开发难度高,ART介于两者之间,并且不影响现有开发模式,所以Google选了ART.我们的技术工程师对此做了技术解读: 1)JNI:在开发过程中使用编译器在C/C++等语言直接编译成机器码,运行的时候能够充分利用系统性能,这是最快的.i

安卓binder机制浅析

Binder机制是android系统中跨进程通信的重要手段.其中,Service与Activity的交互通信使用到了这一机制.为此,我写了service的小案例,以此来方便更好地理解binder通信机制. Service代码: public class MyService extends Service { public boolean flag=true; int count; //实例化一个binder ServiceBinder serviceBinder=new ServiceBinde

安卓IPC机制之Binder详解

IPC(Inter-Process Communication,跨进程通信)是指两个进程之间数据交换的过程,因此我们首先必须了解什么是进程,什么是线程. 进程:进程是正在运行的程序的实例,与程序相比,它更强调动态的概念,与线程相比,进程是线程的容器,一个进程可以包含多个线程但至少包含一个线程.进程是任务调度的基本单位,是系统资源的分配单位. 线程:线程是进程中的一条执行路径,它只能隶属于某一个进程,在支持多线程的操作系统或程序设计语言中(如java),线程是任务调度的单位,但它不是系统资源分配的

13.安卓消息处理机制

1.Android消息处理机制(★★★★必会) 1.1.Looper.Message.Handler的关系 当我们的Android应用程序的进程一创建的时候,系统就给这个进程提供了一个Looper,Looper是一个死循环,它内部维护这个一个消息队列.Looper不停地从消息队列中取消息(Message),取到消息就发送给了Handler,最后Handler根据接收到的消息去修改UI.Handler的sendMessage方法就是将消息添加到消息队列中. 1.2.runOnUiThread Ac

安卓Handler机制的例子

Handler机制是实现线程之间通讯的一种很常见的方法,很多时候都会用到. package com.lab.activity; import android.app.Activity; import android.app.Dialog; import android.app.ProgressDialog; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.

安卓执行机制JNI、Dalvik、ART之间的比較 。android L 改动执行机制。

Android L默认採用ART执行环境.全然兼容64位移动处理器.Google称这将比此前的Dalvik模式性能提高两倍,可是会占用很多其它的内存空间.Android有三种执行模式:JNI.Dalvik.ART.Dalvik明显是最慢的,全然的JNI模式是最快的可是开发难度高,ART介于两者之间.而且不影响现有开发模式,所以Google选了ART.我们的技术project师对此做了技术解读: 1)JNI:在开发过程中使用编译器在C/C++等语言直接编译成机器码.执行的时候可以充分利用系统性能,

安卓Binder机制简析

转自:http://www.linuxidc.com/Linux/2011-07/39271.htm 摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder具有无可比拟的优势.深入了解Binder并将之与传统 IPC做对比有助于我们深入领会进程间通信的实现和性能优化.本文将对Binder的设计细节做一个全面的阐述,首先通过介绍Binder通信模型和 B

安卓事件处理机制

当触摸屏幕时候, --先调用Activity中的dispatchTouchEvent函数,分发事件,找到点击位置所在的第一个子控件viewgroup1, --然后将事件传递个viewgroup1的dispatchTouchEvent函数,然后看viewgroup1的onInterceptTouchEvent()是否拦截,ture,拦截,不向下传递.false,拦截,向下传递,因为viewGroup下还包括子View,所以默认返回值为false,即不拦截此ACTION_DOWN事件. --然后找到

IOS与安卓的区别

1.软件工程,一个项目的流程是--? 简单的说就是:需求确认--概要设计--详细设计--编码--单元测试--集成测试--系统测试--维护  需求确认:需求规格说明书  概要设计:系统用例图,用例场景  详细设计:系统设计报告,数据库设计报告  测试:测试用例报告 2.软件测试流程? 测试准备-测试计划-测试需求-测试用例-测试执行-测试缺陷管理-测试报告总结 注:需求分析需求分析(Requirment Analyzing)应该说是软件测试的一个重要环节,测试开发人员对这一环节的理解程度如何将直接