您的位置:首页 > 移动开发 > Android开发

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

2012-03-20 00:18 776 查看

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 中有消息的循环分发机制。下面介绍下内部的大致流程:当将一个消息通过 sendMessage 交给 Handler 的时候,就是交给了 Looper;
Looper 将消息发送到这个消息指定的 target,而这个“指定”的动作是在 Handler 内部完成的,就是指定为 Handler 自己。
Looper 将这个消息发送给 target 的 dispatchMessage 函数处理,因为 Handler 指定了 target 是自己,所以就是 Handler 的dispatchMessage 函数。
dispatchMessage 函数对该消息进行处理的时候,调用的是 handleMessage,就是由我们自己 override 的那个函数。

Reference

http://weizhulin.blog.51cto.com/1556324/323922 http://blog.csdn.net/Innost/article/details/6055793 -转载请注明来自“柳大·Poechant的CSDN博客”:blog.CSDN.net/Poechant-
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: