• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android的Message Pool是什么——源码角度分析,androidpool

Android的Message Pool是什么——源码角度分析,androidpool

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了messagepool,android.os.message,android messagequeue,android message,android中message等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android的Message Pool是什么——源码角度分析,androidpool


原文地址:

      http://blog.csdn.net/xplee0576/article/details/46875555

 

Android中,我们在线程之间通信传递通常采用Android的消息机制,而这机制传递的正是Message。

通常,我们使用Message.obtain()和Handler.obtainMessage()从Message Pool中获取Message,避免直接构造Message。

  • 那么Android会否因为Message Pool缓存的Message对象而造成OOM呢?对于这个问题,我可以明确的说APP不会因Message Pool而OOM。至于为什么,可以一步步往下看,心急的可以直接看最后一节——Message Pool如何存放Message。

Message Obtain分析:

  Message.obtain()源码:

    /**
     * Return a new Message instance from the global pool. Allows us to
     * avoid allocating new objects in many cases.
     */
    public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }

从代码片中,可以看到Message是直接由sPool赋值的。

Handler.obtainMessage()源码

    /**
     * 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.obtain()最终还是调用Message.obtain()来获取的。

Message Pool相关源码分析

  Message Pool数据结构

    // sometimes we store linked lists of these things
    /*package*/ Message next;

    private static final Object sPoolSync = new Object();
    private static Message sPool;
    private static int sPoolSize = 0;

    private static final int MAX_POOL_SIZE = 50;

    private static boolean gCheckRecycle = true;

从代码中可以很明确的看到,Message Pool的数据结构实际就是一个链表。sPool就是一个全局的消息池,sPoolSize记录链表长度,MAX_POOL_SIZE表示链表的最大长度为50。

Message Pool如何存放Message

    /** @hide */
    public static void updateCheckRecycle(int targetSdkVersion) {
        if (targetSdkVersion < Build.VERSION_CODES.LOLLIPOP) {
            gCheckRecycle = false;
        }
    }

    /**
     * Return a Message instance to the global pool.
     * <p>
     * You MUST NOT touch the Message after calling this function because it has
     * effectively been freed.  It is an error to recycle a message that is currently
     * enqueued or that is in the process of being delivered to a Handler.
     * </p>
     */
    public void recycle() {
        if (isInUse()) {
            if (gCheckRecycle) {
                throw new IllegalStateException("This message cannot be recycled because it "
                        + "is still in use.");
            }
            return;
        }
        recycleUnchecked();
    }

    /**
     * Recycles a Message that may be in-use.
     * Used internally by the MessageQueue and Looper when disposing of queued Messages.
     */
    void recycleUnchecked() {
        // Mark the message as in use while it remains in the recycled object pool.
        // Clear out all other details.
        flags = FLAG_IN_USE;
        what = 0;
        arg1 = 0;
        arg2 = 0;
        obj = null;
        replyTo = null;
        sendingUid = -1;
        when = 0;
        target = null;
        callback = null;
        data = null;

        synchronized (sPoolSync) {
            if (sPoolSize < MAX_POOL_SIZE) {
                next = sPool;
                sPool = this;
                sPoolSize++;
            }
        }
    }

从代码分析上看,消息池存放的核心方法就是上面的recycleUnchecked()方法:

1、将待回收的Message对象字段置空(避免因Message过大,使静态的消息池内存泄漏)。因此无论原先的Message对象有多大,最终被缓存进Message Pool前都被置空,那么这些缓存的Message对象所占内存大小对于一个app内存来说基本可以忽略。所以说,Message Pool并不会造成App的OOM。

2、以内置锁的方式(线程安全),判断当前线程池的大小是否小于50。若小于50,直接将Mesaage插入到消息池链表尾部;若大于等于50,则直接丢弃掉,那么这些被丢弃

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Android的Message Pool是什么——源码角度分析,androidpool

相关文章

  • 2017-05-26如何处理 android 方法总数超过 65536 . the number of method references in a .dex file exceed 64k,android.dex
  • 2017-05-26Android基础部分再学习---activity的状态保存
  • 2017-05-222.3.3 Button(按钮)与ImageButton(图像按钮)
  • 2017-05-26Android 6.0 系统棉花糖新的特性和功能
  • 2017-05-26win通过dos配置注册列表
  • 2017-05-26Android开发学习——打电话应用,android开发打电话
  • 2017-05-26android ndk开发(二)实现一个官方demo,androidndk
  • 2017-05-26再见NullPointerException。在Kotlin里null的处理(KAD 19),kotlinnull
  • 2017-10-21在Mac系统中 下载、安装AndroidStudio
  • 2018-01-28揭开AssetBundle庐山真面目(二)

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • URL转换成二维码,url
    • android View绘制源码分析
    • ViewPager和Fragment的组合使用,viewpagerfragment
    • 手机安全卫士——软件管理-用户程序和系统程序,安全卫士系统程序
    • andriod 获取电池的信息,andriod获取电池
    • App更新之dialog数字进度条,appdialog进度条
    • Android之文件数据存储,android数据存储
    • 缓存之 ACache
    • 关于JNI的使用方法,JNI使用方法
    • Androidstudio中导入内部依赖模块总结,androidstudio模块

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有