Handler本质简析与使用实例

转载 2012年03月28日 13:37:10

Android 开发之道(10)Handler本质简析与使用实例

  • 作者:柳大·Poechant
  • 邮箱:zhongchao.ustc@gmail.com
  • 博客:blog.csnd.net/poechang
  • 日期:March 19th, 2012

1 Overview

先浅析本质太过抽象,还是先上 Handler 的最简实例吧。

  • 功能:Android.os.Handler负责接收,并按计划发送和处理消息;
  • 特点:处理消息是阻塞式的;
  • 本质:关于Handler的内部机制,及其与Looper的关系,请看本文的第三部分“消息处理机制的本质”。

2 Get Started

2.1 先创建一个 Handler 对象,

private Handler mHandler = new Handler();

但这样的Handler是没用的。不过先暂且不要管,往下面看。

2.2 向 Handler 的消息队列发送数据

发送数据的动作是通过 sendMessage 完成的。

Message message = new Message();  
message.what = 1;

// 将消息发送到mHandler的消息队列的最后
mHandler.sendMessage(message);

不过实际上,在 Handler 内部有一个 Looper 类,而消息队列其实是 Looper 的一个成员。Handler 中的 mQueue 就是其成员 mLooper 的 mQueue。

2.3 处理消息队列中的数据

Handler 可以根据 Message 中的 what 值的不同来分发处理,Handler 中提供了 handleMessage 来让开发人员进行 Override。示例如下:

public void handleMessage(Message msg) {
    switch (msg.what) {
    case 1:
        // 所做的操作
        break;
    case 2:
        // 所做的操作
        break;
    default:
        // 所做的操作
    }
};

完整的写法,就是在创建 Handler 对象时如下:

private Handler mHandler = new Handler() {
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case 1:
            // 所做的操作
            break;
        case 2:
            // 所做的操作
            break;
        default:
            // 所做的操作
        }
    };  
}

2 计时器简例

2.1 先创建一个任务类

Timer 和 TimerTask 是 Java 语言中的类,如果不熟悉,请看下面的例子及注视。

// 任务类
private class MyTask extends TimerTask{
    @Override
    public void run() { 
        // 创建要发送的消息
        Message message = new Message();  
        message.what = 1;

        // 将消息发送到mHandler的消息队列的最后
        mHandler.sendMessage(message);
    }     
}

使用方法很简单,就是用 Timer 来作为容器:

// 创建用于执行任务类的Timer
Timer timer = new Timer();

// 1毫秒之后开始每隔5秒钟执行一次MyTast
timer.scheduleAtFixedRate(new MyTask(), 1, 1000);  

2.2 完整的例子

布局文件就省略了,源码如下:

package com.sinosuperman.android;

import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
public class Test extends Activity {

    //title为setTitle方法提供变量,这里为了方便我设置成了int型  
    private int mSecs = 0;  

    private Handler mHandler = new Handler(){
        // 根据mHandler的消息队列中的不同消息进行处理
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case 1:
                // 所做的操作
                updateTitle();  
                break;  
            }  
        };
    };

    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);

        // 创建用于执行任务类的Timer
        Timer timer = new Timer();

        // 1毫秒之后开始每隔5秒钟执行一次MyTast
        timer.scheduleAtFixedRate(new MyTask(), 1, 1000);  
    }

    // 任务类
    private class MyTask extends TimerTask{
        @Override
        public void run() {

            // 创建要发送的消息
            Message message = new Message();  
            message.what = 1;

            // 将消息发送到mHandler的消息队列的最后
            mHandler.sendMessage(message);
        }     
    }

    // 处理消息所做的操作
    public void updateTitle(){
        setTitle("Michael's Timer: " + mSecs);  
        mSecs++;  
    }  
}

3 消息处理机制的本质

3.1 Looper 与 Handler 的内部机制

Looper 中有一个 MessageQueue 的成员,Looper 中还有有一个 loop 函数用来对消息队列进行循环。Looper 并不直接与 Handler 绑定,我们可以直接“玩弄” Looper,不过 Handler 让我们“玩弄”她更容易一些。

Handler 本质上是一个工具类,其内部有 Looper 成员。我们通过 Handler 类完成消息的发送和处理、制定分发机制等等。

3.2 消息处理机制的本质

Handler 中封装了 Looper 成员,Handler 中的消息队列就是 Looper 中的消息队列成员。Looper 中有消息的循环分发机制。下面介绍下内部的大致流程:

  1. 当将一个消息通过 sendMessage 交给 Handler 的时候,就是交给了 Looper;
  2. Looper 将消息发送到这个消息指定的 target,而这个“指定”的动作是在 Handler 内部完成的,就是指定为 Handler 自己。
  3. Looper 将这个消息发送给 target 的 dispatchMessage 函数处理,因为 Handler 指定了 target 是自己,所以就是 Handler 的dispatchMessage 函数。
  4. dispatchMessage 函数对该消息进行处理的时候,调用的是 handleMessage,就是由我们自己 override 的那个函数。

Reference

  1. http://weizhulin.blog.51cto.com/1556324/323922 
  2. http://blog.csdn.net/Innost/article/details/6055793

-

From : http://blog.csdn.net/poechant/article/details/7371461

Android开发之道(10)Handler本质简析与使用实例

Android 开发之道(10)Handler本质简析与使用实例作者:柳大·Poechant邮箱:zhongchao.ustc@gmail.com博客:blog.csnd.net/poechang日期...

Android 开发之道(10)Handler本质简析与使用实例

Android 开发之道(10)Handler本质简析与使用实例 作者:柳大·Poechant邮箱:zhongchao.ustc@gmail.com博客:blog.csnd.net/poecha...

Android的IPC机制(七)—— Socket的原理简析与使用

在前面的几篇文章中,我们介绍了许多在Android中有关进程间通信的方式,但都是在一个设备上进行的进程间通信,而这时候我们两个应用在不同的设备上的时候,在这个时候我们就不能通过前方介绍的那些方法来解决...
  • ljd2038
  • ljd2038
  • 2016年03月06日 20:54
  • 4172

Socket的原理简析与使用

在前面的几篇文章中,我们介绍了许多在Android中有关进程间通信的方式,但都是在一个设备上进行的进程间通信,而这时候我们两个应用在不同的设备上的时候,在这个时候我们就不能通过前方介绍的那些方法来解决...

VPN的简析与架设接入

  • 2008年06月29日 10:39
  • 1.1MB
  • 下载

各大网站瀑布流简析与建议

很难说这东西是什么时候山寨到国内,反正现状就是一涌而上,到处是瀑布流。瀑布流的鼻祖是Pinterest,图片网。图片网令我想起了各种相册,如最著名的Flickr。但区区Pinterest一小站,能够独...

vbs简析与应用

  • 2014年05月29日 19:40
  • 156KB
  • 下载

Windows打印体系结构简析与虚拟打印

这两天整理以前的论文,把那时候的毕业设计又翻出来温习了一下。 虚拟打印机驱动程序。当时一直没有太搞懂自己编写的打印驱动究竟是怎么个角色, 所谓的迷你驱动和微软统一驱动又有啥不同。呵呵,可以...

SOAP结构简析与编写方式

  • 2010年07月26日 10:48
  • 23KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Handler本质简析与使用实例
举报原因:
原因补充:

(最多只允许输入30个字)