Android sendMessage 与 obtainMessage (sendToTarget)比较
话说在工作中第一次接触android 的Handler 的时候,不知道怎么去关注性能。
记得当时这么写的:
Message msg = new Message()
msg.what = xxx;
msg.arg1 = xxx;
msg.arg2 = xxx;
handler.sendMessage(msg);
这样写也没有绝得不好,反正当时项目的功能实现了。(性能上还可以)
后来没事的时候看了看handler 的其他的方法,就看到了obtainMessage()这个方法.很奇怪,不知道为何还要出来的方法
本来上面的那段code 就能实现handler 的功能了,为什么还要出现他,后来百度google 一把,大家说 什么性能上有差别之
类的。。。。。结果可想而知(大部分的文章都是你抄我的我抄你的,技术就是这样出来的。。鄙视这种抄写别人博客文章而
不著名转载出处的人)。于是我就去看源码能否看到一些好的描述。
Message msg = handler.obtainMessage();
msg.what = xxx;
msg.arg1 = xxx;
msg.arg2 = xxx;
msg.obj = xxx; ....................
看看这两段代码其实就是方法不一样 ,参数都一样。但是为何实现的效果一样还要分离出来这么多方法呢?
到源码去看个究竟吧!
先去看sendMessage()这个方法。。。。它调用的是Handler 中的sendMessage(Message msg)
源码 片段1 如下:
/**
* Pushes a message onto the end of the message queue after all pending messages
* before the current time. It will be received in {@link #handleMessage},
* in the thread attached to this handler.
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, );
}
再看handler.obtainMessage()源码 片段2 如下:
/**
* Returns a new {@link android.os.Message Message} from the global message pool.
* More efficient than creating and allocating new instances.
* The retrieved message has its handler set to this instance
* (Message.target == this).
* If you don't want that facility, just call Message.obtain() instead.
*/ public final Message obtainMessage()
{
return Message.obtain(this);
}
上面这两段都是Handler 里面的方法,不过在片段1 我们可以看到Message是我们作为参数传过去的,片段2的则是我们
Message帮我们处理,它调用obtain(Handler h)方法,之后我们还要调用Message中sendToTarget()这个方法。
看一下Message.obtain(Hanlder h) 的源码 代码片段3如下:
/**
* Same as {@link #obtain()}, but sets the value for the <em>target</em> member on the Message return * ed.
* @param h Handler to assign to the returned Message object's <em>target</em> member.
* @return A Message object from the global pool.
*/
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h; return m;
}
再看 sendToTarget() 源码 代码片段4 如下:
/**
* Sends this Message to the Handler specified by {@link #getTarget}.
* Throws a null pointer exception if this field has not been set.
*/
public void sendToTarget() {
<span style="background-color:#ff0000"> target.sendMessage(this);</span>
}
这里的target就是handler,sendToTarget()又在调用handler的 sendMessage 方法了。。。
看到这里也许有的人很疑惑,这样转来转去,转了一圈怎么又回到Handler的 sendMessage方法了?那么性能比较一说
还有其他的证据么?(难道调用的方法多性能就低么?也许有这么一点原因,不过这里几乎可以不考虑这一点性能损耗的)
那么性能的比较证据应该从哪里找呢?
其实细心的同学已经看到了,注意看源码的注释,
/**
* Returns a new {@link android.os.Message Message} from the global message pool. More efficient than
* creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this).
* If you don't want that facility, just call Message.obtain() instead.
*/
这里我们的Message 已经不是 自己创建的了,而是从MessagePool 拿的,省去了创建对象申请内存的开销。。。。。
到这里大家应该都明白了。所以以后使用的时候尽量使用 Message msg = handler.obtainMessage();的形式创
建Message,不要自己New Message 至于message产生之后你使用obtainMessage 或者是 sendMessage 效率影响
并不大.同时我们也要注意以后谈论性能的时候要找准位置,譬如这里性能的问题不是在调用 obtainMessage 和 sen
dMessage 的方法上,而是调用他们之前对象的创建问题上。
加深阅读:
对handler的通信一直是按原照搬的写了很长一段时间了,今天才突然发现,还真不太理解里面的参数,悲剧啊,在handler.obtainMessage()的参数是这样写的:
Message android.os.Handler.obtainMessage(int what, int arg1, int arg2, Object obj)
public final Message obtainMessage (int what, int arg1, int arg2, Object obj)
Since: API Level 1
Same as obtainMessage(), except that it also sets the what, obj, arg1,and arg2 values on the returned Message.
Parameters
what Value to assign to the returned Message.what field.
arg1 Value to assign to the returned Message.arg1 field.
arg2 Value to assign to the returned Message.arg2 field.
obj Value to assign to the returned Message.obj field.
Returns
A Message from the global message pool.
不知道这WHAT到底是指什么:
01-27 02:41:47.853: INFO/System.out(581): Msg:{ what=1001 when=6260065 arg1=1002 arg2=1003 obj=Main Thread send For info! }
01-27 02:41:47.853: INFO/System.out(581): Msg.what:1001
01-27 02:41:47.853: INFO/System.out(581): Msg.arg1:1002
01-27 02:41:47.853: INFO/System.out(581): Msg.arg1:1003
01-27 02:41:47.892: INFO/System.out(581): Msg.Obj:Main Thread send For info!
上面的what我自己定义了下,为什么会有那个when呢,当在多数点击的时候:
01-27 02:50:39.522: INFO/System.out(581): Msg:{ what=1001 when=6791734 arg1=1002 arg2=1003 obj=Main Thread send For info! }
01-27 02:50:39.522: INFO/System.out(581): Msg.what:1001
01-27 02:50:39.532: INFO/System.out(581): Msg.arg1:1002
01-27 02:50:39.532: INFO/System.out(581): Msg.arg1:1003
01-27 02:50:39.572: INFO/System.out(581): Msg.Obj:Main Thread send For info!
只有那个when是变化的,那个when取的是什么值呢,它的运行机制与目的是什么呢,请大侠们能否解释下,谢谢了.....
再送上removMessage
Hander中removeMessages方法
我的理解:
1、这个方法使用的前提是之前调用过sendEmptyMessageDelayed(0, time),意思是延迟time执行handler中msg.what=0的方法;
2、在延迟时间未到的前提下,执行removeMessages(0),则上面的handler中msg.what=0的方法取消执行;
3、在延迟时间已到,handler中msg.what=0的方法已执行,再执行removeMessages(0),不起作用。
4、该方法会将handler对应message队列里的消息清空,通过msg.what来找到对应的message。
5、当队列中没有message则handler会不工作,但并不是handler会停止,当队列中有新的message进来后,会继续处理执行。
Android sendMessage 与 obtainMessage (sendToTarget)比较的更多相关文章
- Handler sendMessage 与 obtainMessage (sendToTarget)
这篇文章讲的很好: http://www.cnblogs.com/android007/archive/2012/05/10/2494766.html 两种用法: 1. private void se ...
- sendMessage 与 obtainMessage (sendToTarget)比较
我们平时在做到多线程问题的时候可能利用Handler去传递Message,其中,经常使用的就是 1.new Handler().obtainMessage().sendToTarget(); 2.ne ...
- Handler sendMessage 与 obtainMessage (sendToTarget)比较
转自:http://iaiai.iteye.com/blog/1992196 obtainmessage()是从消息池中拿来一个msg 不需要另开辟空间new new需要重新申请,效率低,obtian ...
- Handler.sendMessage 与 Handler.obtainMessage.sendToTarget比较
原文地址: http://www.cnblogs.com/android007/archive/2012/05/10/2494766.html 话说在工作中第一次接触android 的Handler ...
- Android Message和obtainMessage的区别
类概述 定义一个包含任意类型的描述数据对象,此对象可以发送给Handler.对象包含两个额外的int字段和一个额外的对象字段,这样可以使得在很多情况下不用做分配工作. 尽管Message的构造器是公开 ...
- Android Message和obtainMessage的差别
前几天须要实现一个以太网功能就看了以太网的源代码部分,看见了源代码部分在消息处理时,发现有一些不同的地方: 平时我在处理消息时: 1.首先创建Handler对象: private Hand ...
- Android handler.obtainMessage()
在handler.obtainMessage()的参数是这样写的: Message android.os.Handler.obtainMessage(int what, int arg1, int a ...
- Android 下载模块分析(DownloadManager和DownloadProvider)
Android下载模块主要有2个部分组成:DownloadManager和DownloadProvider:其中DownloadManager提供接口供调用,具体的实现是 DownloadProvid ...
- 我的Android进阶之旅------>Android中AsyncTask源码分析
在我的<我的Android进阶之旅------>android异步加载图片显示,并且对图片进行缓存实例>文章中,先后使用了Handler和AsyncTask两种方式实现异步任务机制. ...
随机推荐
- .NET开发Windows Service程序 - Topshelf
在实际项目开发过程中,会经常写一些类似定时检查,应用监控的应用.这类应用在windows平台通常都会写成window service程序. 在百度上搜索一下'c#开发windows service', ...
- Ubuntu下codeblocks汉化
code::blocks是一个十分好用编辑环境,一个在手,无所不能,为了更好的支持中文,我列出了汉化的方法: 1下载中文汉化包:http://pan.baidu.com/s/1hqvNZbI 2.解压 ...
- .net 科学类型相关问题
Q:如果我要把使用科学记数法表示的string转换为int又该如何呢? A:你可以通过把NumberStyles.AllowDecimalPoint | NumberStyles.AllowExpon ...
- .net 自然排序方式
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...
- MVC的Ajax的异步请求
MVC的Ajax的异步请求 在这里小写一下MVC的异步请求的一点小总结. 个人认为是有两种的,一种就是跟webform一样的,依旧是使用jQuery的$.get()方法,只是请求地址不同,webfor ...
- 【转】如何设置Android软键盘的默认不弹出?
在开发Anroid的时候,当你打开一个界面的时候,屏幕的焦点会自动停留在第一个EditText中,Android的软键盘默认会自动弹出,用户第一眼连界面都没有看清楚,软键盘就弹出来了,这就影响到了用户 ...
- Text selection in div(contenteditable) when double click
背景: 在最近项目中,碰到一个问题:有一个可编辑的div需要双击时可编辑,blur或者回车时将编辑结果保存.你可能注意到双击时,文字会被选中,可编辑区域不会focus到光标位置.考虑到兼容性问题,写了 ...
- C#WinForm中在dataGridView中添加中文表头
第一步: 注意事项:(1)如果使用数据库,那么第三步的名称可以是任意的,但是不能和数据库中的列名一样,否则会报错: (2)第四步的页眉文本就是你想用的中文列名,自己定: (3)第六步尤其重要,不 ...
- 【DP】BZOJ 1260: [CQOI2007]涂色paint
1260: [CQOI2007]涂色paint Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 893 Solved: 540[Submit][Stat ...
- 关于在js中使用csstext的问题
会将前边所设置的css属性全部清空,慎用!