前言: 很早以前,学习android的时候就接触过Handler ,知道Handler是一个用于线程间通信的类,最常用于做下载条,最近,看了Pro android 3 这本书,里面描述的Handler 说得非常的细致,与此,写下Handler的学习笔记

Android 运行的进程

为了,更好的了解Handler的机制,我们应该首先,将Android系统整个运行进程都要烂熟于心,下面是android 进程运行图:

从图中我们可以看到,当我们从外部调用组件的时候,Service 和 ContentProvider 是从线程池那里获取线程,而Activity 和BroadcastReceiver是直接在主线程运行,为了,追踪线程,我们可以用debug 方法,或者使用一个工具类,这里,我们创建一个用于监视线程的工具类

/** * @author Tom_achai * @date 2011-11-20 *  */public class Utils {public static long getThreadId(){Thread t = Thread.currentThread();return t.getId();}/** * 获取单独线程信息 * @return */public static String getThreadSignature(){Thread t = Thread.currentThread();long l = t.getId();String name = t.getName();long p = t.getPriority();String gname = t.getThreadGroup().getName();return ("(Thread):"+name+":(id)"+ l +"(:priority)" + p + ":(group)" + gname );}/** *获取当前线程 信息 */public static void logThreadSignature(){Log.d("ThreadUtils", getThreadSignature());}public static void logThreadSignature(String name ){Log.d("ThreadUtils", name + ":"+getThreadSignature());}public static void sleepForInSecs(int secs){try{Thread.sleep(secs * 1000);}catch (Exception e) {// TODO: handle exceptione.printStackTrace();}}/** * 讲String放进Bundle 中 * @param message * @return */public static Bundle getStringAsBundle(String message){Bundle b = new Bundle();b.putString("message", message);return b;}/** *  * 获取Bundle的String * @param b * @return */public static String getStringFromABundle(Bundle b){return b.getString("message");}}

有了这样一个类就可以方便我们观察线程的运行

好了,现在准备好以后就进入正题Handler

Handlers

为什么要使用Handlers?

因为,我们当我们的主线程队列,如果处理一个消息超过5秒,android 就会抛出一个 ANP(无响应)的消息,所以,我们需要把一些要处理比较长的消息,放在一个单独线程里面处理,把处理以后的结果,返回给主线程运行,就需要用的Handler来进行线程建的通信,关系如下图;

下面是Handler,Message,Message Queue 之间的关系图

这个图有4个地方关系到handlers

1, 主线程(Main thread)

2, 主线程队列(Main thread queue)

3,Hanlder

4,Message

上面的四个地方,主线程,和主线程的队列我们无需处理,所以,我们主要是处理Handler 和 Message 之间的关系.

我们每发出一个Message,Message就会落在主线程的队列当中,然后,Handler就可以调用Message绑定的数据,对主线程的组件进行操作.

Message

作为handler接受的对象,我们有必要知道Message这个数据类型是个怎样的数据类型

从官方文档中我们可以知道message 关于数据的字段

public int what
public int arg1
public int arg2
public Object obj

从上面的表格可以看出,message 提供了一个对象来存储对象,而且,还提供了三个int字段用来存储少量int类型

当然,除了以上三个Message 自有的字段外,我们还可以通过setData(Bundle b),来存储一个Bundle对象,来存储更丰富的数据类型,例如,图片等等.

在初始化我们的message的时候就可以为我们的Message默认字段赋值,注意赋值顺序!!!

Message msg = obtainMessage();//设置我们what 字段的初值,注意顺序!!!Message msg = mHandler.obtainMessage(int what);//下面同理Message msg = mHandler.obtainMessage(int what,Object object);Message msg = mHandler.obtainMessage(int what,int arg1,int arg2);Message msg = mHandler.obtainMessage(int what,int arg1,int arg2, Object obj);

更多相关文章

  1. Android简易注解View(java反射实现)
  2. Android中对Log日志文件的分析
  3. 《Android经验分享》周刊第1期
  4. Android中关于线程使用的几点注意事项
  5. Android节拍器&定时程序
  6. Android节拍器
  7. Android消息机制——Handler、Looper、MessageQueue
  8. Android的线程模型
  9. Android的消息处理机制(深入源码)

随机推荐

  1. Android(安卓)EditText 限制只能输入指定
  2. Android上对非标准RSS进行解析之后的反思
  3. 《Android(安卓)Studio实用指南》4.27 使
  4. 为什么Android将掀起一场手机领域的狂风(
  5. No suitable java found.In order to pro
  6. 浅谈应用工厂模式和单例在Android中实现
  7. Android(安卓)中的进程
  8. Android-几行代码通知系统自动安装apk
  9. 在android的spinner中,实现key(id)和Value
  10. 【Android学习总结】之eclipse工程目录结