演讲前,AsyncTask文章。我们在最后谈到。AsyncTask它是利用Handler异步消息处理机制,操作结果。使用Message回到主线程,从而执行UI更新线程。

而在我们的日常开发工作,Handler一类是经常使用在我们中间,然后Handler的主要作用是什么?

Handler 的主要作用就是对消息(消息能够是我们想做的一些UI更新,也能够是其它的一些不可见的操作,如操作数据库等)的异步处理机制。而相信大家都了解异步的概念。

简单地说一下:

1)从程序的角度来看,就是当运行某行代码的时候,发送了一个异步请求(消息)。程序不须要在此行代码上继续等待下去。而是可以继续运行之后的代码。

2)从用户的角度来看,用户发送了一个消息。不须要什么事也不做,就在那傻等,而能够去做其它的事情。当相应的消息被处理完之后 ,就会通过回调机制处理相应的结果。

所以。Android中Handler的消息异步处理机制,可以给用户提供一个更加合理及友好的用户体验。

当然。Android是用Handler来实现。其它的平台环境。也有着自己的一套异步实现机制,原理一样,名称不同而已。

既然我们是做Android开发的。那么我们肯定就要好好地学习一下Handler的使用。探究一下隐藏在Handler之后的代码架构。

首先。我们还是从简单的样例来入门。学习一下,怎样使用Handler。

代码例如以下:

public class MainActivity extends ActionBarActivity {

    private static final int MSG_ID_1 = 1;
private static final int MSG_ID_2 = 2; private Handler mHandler = new Handler() { public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_ID_1:
Log.v("Test", "Toast called from Handler.sendMessage()");
break;
case MSG_ID_2:
break;
} }
}; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); Message message = mHandler.obtainMessage();
message.what = MSG_ID_1;
mHandler.sendMessage(message);
}
}

当我们启动程序的时候。我们能够看到,在LogCat里面就会看到,已经打印出了例如以下的信息:

10-27 15:13:21.382: V/Test(9618): Toast called from Handler.sendMessage()

而这正是我们在handler的handleMessage中对msg.what = MSG_ID_1 的情况下进行处理的。

从这个简单的样例,我们能够归纳一下Handler的使用步骤,大概有下面几步:

1)创建一个Handler对象。而且实现其 handleMessage(Message msg) 方法,如代码中:

private Handler mHandler = new Handler() {

而实现handleMessage方法一步。我们能够看到,会获取一个Message对象。

Message对象封装了一些參数。经常使用的大概有下面几个:

a)what 參数:这是一个 int 值,常常是我们用来区分消息的一个ID,比方样例中,我们将MSG_ID_1在创建消息的时候赋值给msg.what。

b)obj 參数:这是一个Object对象。

通过obj參数,能够把不论什么对象赋给消息,然后在handleMessage中进行处理,而这也是Handler在异步处理中传递数据的方法。

c)arg1, arg2 等參数:上述a),b) 两个參数是我们最经常使用的Message的參数了,基本上也须要这两个參数就足够了,只是Message还是提供了其它的一些字段供我们使用。如argX等。也就是 arguments的缩写。arg1和arg2是Android提供的所谓low-cost的变量,只是一般也就是用来设置一些int值。

d)data參数,data參数是一个Bundle类型的对象,我们能够通过setData方法来设置bundle。就跟我们在Activity之间利用Intent传递数据一样来使用。

2)当创建好Handler对象之后,第二步就须要创建一个Message对象了。创建Message对象有两种方法:

2.1)直接创建新对象,代码例如以下:

Message msg = new Message()

2.2)利用Handler.obtainMessage()方法,也即上面代码中使用的方式。例如以下:

Message message = mHandler.obtainMessage();

普通情况下,我们建议使用另外一种方式。为什么呢?

由于在Message的内部中维护了一个类似消息池的对象,当我们使用Handler来对Message进行分发的时候,处理完之后,Message对象并不一定会被立即销毁。而是有可能放到一个消息池中。

当利用Handler的obtainMessage方法,Handler会去从消息池中获取一个已经存在的对象。并初始化好其信息。这样,我们就不须要再又一次去创建一个对象,浪费一些内存,在嵌入式应用,内存不是非常大的情况下,这是对性能的一种优化。

在创建Message的时候,我们就能够对msg.what进行赋值,目的就是为了Handler在handleMessage的时候,能够推断这个消息的用途或目的是什么。

当然,不同的需求,肯定有不同的处理。这就详细情况详细分析了。

3)当消息(Message)创建好了之后,我们就能够利用Handler的sendMessage来进行发送消息了,之后。这个消息就会被其handler所捕获,从而进行处理了。

接下来,我们就再扩充一下这个样例,代码例如以下:

public class MainActivity extends ActionBarActivity {

    private static final int MSG_ID_1 = 1;
private static final int MSG_ID_2 = 2; private Handler mHandler = new Handler() { public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_ID_1:
Log.v("Test", "Toast called from Handler.sendMessage()");
break;
case MSG_ID_2:
String str = (String) msg.obj;
Log.v("Test", str);
break;
} }
}; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); Message message = mHandler.obtainMessage();
message.what = MSG_ID_1;
mHandler.sendMessage(message); Message msg2 = mHandler.obtainMessage();
msg2.obj = "I'm String from Message 2";
msg2.what = MSG_ID_2;
mHandler.sendMessage(msg2);
}
}

而其相应的结果例如以下:

10-27 15:35:19.168: V/Test(12135): Toast called from Handler.sendMessage()
10-27 15:35:19.168: V/Test(12135): I'm String from Message 2

由此,我们能够看到。利用obj參数,我们将String对象给传到handleMessage中去了。

除了 sendMessage方法,发送消息时, Handler还可使用例如以下的方法:

public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }     public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }

而事实上,不管是还是sendMessage还是使用post方法,事实上终于都是通过调用sendMessageAtTime方法,将相应的Message对象放入一个MessageQueue中的。

那么其为什么要放到MessageQueue?放到MessageQueue中有怎样跑回到Handler的handleMessage中的呢?

接下来的文章。我们再继续来学习。

这一篇我们就简单介绍了如何使用Handler,简单的示例。只是入门。

结束。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

Android正在使用Handler实现消息分发机制(零)的更多相关文章

  1. Android正在使用Handler实现消息分发机制(两)

    在开始这篇文章之前,.首先,我们在总结前两篇文章Handler, Looper和MessageQueue像一些关键点: 0)在创建线程Handler之前,你必须调用Looper.prepare(), ...

  2. Android中利用Handler实现消息的分发机制(三)

    在第二篇文章<Android中利用Handler实现消息的分发机制(一)>中,我们讲到主线程的Looper是Android系统在启动App的时候,已经帮我们创建好了,而假设在子线程中须要去 ...

  3. delphi VCL研究之消息分发机制-delphi高手突破读书笔记

    1.VCL 概貌 先看一下VCL类图的主要分支,如图4.1所示.在图中可以看到,TObject是VCL的祖先类,这也是Object Pascal语言所规定的.但实际上,TObject以及TObject ...

  4. Cocos2d-x 3.0 屏幕触摸及消息分发机制

    ***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...

  5. Android 消息分发机制

    Android 中针对耗时的操作,放在主线程操作,轻者会造成 UI 卡顿,重则会直接无响应,造成 Force Close.同时在 Android 3.0 以后,禁止在主线程进行网络请求. 针对耗时或者 ...

  6. Android为TV端助力 事件分发机制

    android事件分发机制,给控件设置ontouch监听事件,当ontouch返回true时,他就不会走onTouchEvent方法,要想走onTouchEvent方法只需要返回ontouch返回fa ...

  7. Android面试收集录6 事件分发机制

    转自:秋招面试宝典. 一. 基础认知 1.1 事件分发的对象是谁? 答:事件 当用户触摸屏幕时(View或ViewGroup派生的控件),将产生点击事件(Touch事件). Touch事件相关细节(发 ...

  8. 轻松搞定RabbitMQ(二)——工作队列之消息分发机制

    转自 http://blog.csdn.net/xiaoxian8023/article/details/48681987 上一篇博文中简单介绍了一下RabbitMQ的基础知识,并写了一个经典语言入门 ...

  9. Android正在使用Handler实现信息发布机制(一)

    上一篇文章,我们谈到了电话Handler的sendMessage方法,最后,我们将进入一个电话 sendMessageAtTime方法,例如下列: public boolean sendMessage ...

随机推荐

  1. 《SPA设计与架构》之JavaScript模块化

    原文 简书原文:https://www.jianshu.com/p/d5fc38506bc4 大纲 1.什么是模块? 2.基本的模块模式 3.模块模式概念 4.模块结构 5.揭示模式 6.模块编程的意 ...

  2. 美轮美奂宇宙星空制作神器Spacescape

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/46444569 作者:car ...

  3. Android自定义组件系列【2】——Scroller类

    在上一篇中介绍了View类的scrollTo和scrollBy两个方法,对这两个方法不太了解的朋友可以先看<自定义View及ViewGroup> scrollTo和scrollBy虽然实现 ...

  4. 【u011】乘法难题

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 乘法难题是一种用一行的卡片来玩的单人游戏,每张卡片上有一个正整数.在游戏者从中拿出一卡片,并且得到一个 ...

  5. arcengine 要素类的复制

    转自原文arcengine 要素类的复制 using System; using System.Collections.Generic; using System.Text; using ESRI.A ...

  6. 基于 Android NDK 的学习之旅-----环境搭建

    工欲善其事 必先利其器 , 下面介绍下 Eclipse SDK NDK Cygwin CDT 集成开发环境的搭建. 1.Android 开发环境搭建 Android开发环境搭建不是重点,相信看此文章的 ...

  7. Android 解决Android的TextView和EditText换行问题

    最近版本迭代的新增收货地址模块出现地址填写时点击换行,然后网络提交数据到后台,在地址列表查看地址时,也出现换行的问题. 问题效果图: 1.分析原因 用Google的DHC工具进行网络模拟请求,发现返回 ...

  8. 【poj3468】A Simple Problem with Integers

    Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 97008   Accepted: 30285 Case Time Limi ...

  9. [React] Recompose: Override Styles & Elements Types in React

    When we move from CSS to defining styles inside components we lose the ability to override styles wi ...

  10. matplotlib 可视化 —— cmap(colormap)

    color example code: colormaps_reference.py - Matplotlib 2.0.0 documentation 由其文档可知,在 colormap 类别上,有如 ...