原文地址:

http://www.cnblogs.com/android007/archive/2012/05/10/2494766.html

话说在工作中第一次接触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, 0);
    }

 再看handler.obtainMessage()源码 片段2 如下:

/**
    * Returns a new {@link android.os.Message Message} from the global message pool. <br>   * More efficient than creating and allocating new instances. <br>    * The retrieved message has its handler set to this instance    <br>   * (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=""> 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.sendMessage 与 Handler.obtainMessage.sendToTarget比较的更多相关文章

  1. Handler sendMessage 与 obtainMessage (sendToTarget)比较

    转自:http://iaiai.iteye.com/blog/1992196 obtainmessage()是从消息池中拿来一个msg 不需要另开辟空间new new需要重新申请,效率低,obtian ...

  2. Handler sendMessage 与 obtainMessage (sendToTarget)

    这篇文章讲的很好: http://www.cnblogs.com/android007/archive/2012/05/10/2494766.html 两种用法: 1. private void se ...

  3. Android sendMessage 与 obtainMessage (sendToTarget)比较

    话说在工作中第一次接触android 的Handler 的时候,不知道怎么去关注性能. 记得当时这么写的: Message msg = new Message() msg.what = xxx; ms ...

  4. sendMessage 与 obtainMessage (sendToTarget)比较

    我们平时在做到多线程问题的时候可能利用Handler去传递Message,其中,经常使用的就是 1.new Handler().obtainMessage().sendToTarget(); 2.ne ...

  5. Handler类和Handler,Loop,MessageQueue的工作原理

    原文地址:http://blog.csdn.net/xiyangyang8/article/details/50754771 Handler类的作用主要有两种: 1.在新启动的线程中发送消息. 2.在 ...

  6. Handler消息传递机制——Handler类简洁

    Handler类的主要作用有两个: 在新启动的线程中发送消息. 在主线程中获取.处理消息. 上面的说法很简单,只要分成两步即可:在新启动的线程中发送消息:然后在主线程上获取.并处理消息.但这个过程涉及 ...

  7. Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别?

    一个帖子的整理: Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别如果你不带参数的实例化:Handler ...

  8. new Handler()和new Handler(Looper.getMainLooper())的区别

    一个帖子的整理: Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别如果你不带参数的实例化:Handler ...

  9. W/MessageQueue: Handler (android.os.Handler) {4241f8f8} sending message to a Handler on a dead thread

    缩略信息是: sending message to a Handler on a dead thread 我是用IntentService时报的 稍微纤细一点儿的信息是: Handler (andro ...

随机推荐

  1. Oracle_多表查询

    SQL多表查询 等值和不等值连接查询 从多个表中获取数据:如果在查询的时候,直接从多个表中获取数据.没有添加条件判断,会出现"笛卡尔积"错误 笛卡尔积错误 笛卡尔集会在下面条件下产 ...

  2. Rust初步(七):格式化

    在Rust中,如果要进行屏幕输出,或者写入到文件中,需要对数据进行格式化.这一篇总结一下它所支持的几种格式化方式. 这篇文章参考了以下官方文档,不过,按照我的风格,我还是会突出于C#语言的比较,这样可 ...

  3. 【记录】WCF IIS 404

    WCF IIS 发布报"404错误": 修改 Web.config 如下: <system.webServer> <handlers> <remove ...

  4. WebSocket 介绍(二)-WebSocket API

    这一章介绍如何用WebSocket API来控制协议和创建应用,运用http://websocket.org 提供的现有WebSocket服务器,我们可以收发消息.创建一些简单的WebSocket应用 ...

  5. Net设计模式实例之原型模式( Prototype Pattern)

    一.原型模式简介(Brief Introduction) 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. Specify the kin ...

  6. [Web API] Web API 2 深入系列(6) Model绑定(上)

    目录 解决什么问题 Model元数据解析 复杂类型 ValueProvider ValueProviderFactory 解决什么问题 Model: Action方法上的参数 Model绑定: 对Ac ...

  7. EF是啥?【What is Entity Framework?】(EF基础系列2)

    EF产生的背景: 编写ADO.NET访问数据的代码,是沉闷而枯燥的,所以微软提供了一个对象关系映射框架(我们称之为EF),通过EF可以自动帮助我们的程序自动生成相关数据库. Writing and m ...

  8. C# 关键字extern用法

    修饰符用于声明在外部实现的方法.extern 修饰符的常见用法是在使用 Interop 服务调入非 托管代码时与 DllImport 属性一起使用:在这种情况下,该方法还必须声明为 static,如下 ...

  9. 基于CkEditor实现.net在线开发之路(3)常用From表单控件介绍与说明

    上一章已经简单介绍了CKEditor控件可以编写C#代码,然后可以通过ajax去调用,但是要在网页上面编写所有C#后台逻辑,肯定痛苦死了,不说实现复杂的逻辑,就算实现一个简单增删改查,都会让人头痛欲裂 ...

  10. Class.forName("com.mysql.jdbc.Driver") ;

    try { Class.forName("com.mysql.jdbc.Driver") ; } catch(ClassNotFoundException e) { System. ...