博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android正在使用Handler实现消息分发机制(零)
阅读量:5748 次
发布时间:2019-06-18

本文共 4740 字,大约阅读时间需要 15 分钟。

演讲前,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,简单的示例。只是入门。

结束。

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

你可能感兴趣的文章
负载均衡之Haproxy配置详解(及httpd配置)
查看>>
linux虚拟机拷贝之后联网出错
查看>>
标准与扩展ACL 、 命名ACL 、 总结和答疑
查看>>
查找恶意的TOR中继节点
查看>>
MAVEN 属性定义与使用
查看>>
shell高级视频答学生while循环问题
查看>>
使用@media实现IE hack的方法
查看>>
《11招玩转网络安全》之第一招:Docker For Docker
查看>>
hive_0.11中文用户手册
查看>>
hiveserver2修改线程数
查看>>
XML教程
查看>>
oracle体系结构
查看>>
Microsoft Exchange Server 2010与Office 365混合部署升级到Exchange Server 2016混合部署汇总...
查看>>
Proxy服务器配置_Squid
查看>>
开启“无线网络”,提示:请启动windows零配置wzc服务
查看>>
【SDN】Openflow协议中对LLDP算法的理解--如何判断非OF区域的存在
查看>>
纯DIV+CSS简单实现Tab选项卡左右切换效果
查看>>
栈(一)
查看>>
ios 自定义delegate(一)
查看>>
创建美国地区的appleId
查看>>