在android系统中,message常在多线程之间信息交流中用到,通过Handler来传递线程间的消息(message).今天讨论的是android中的message特性:对象池.

        在android中,google对message有一句这样的英文说明:

       *

While the constructor of Message is public, the best way to get
       * one of these is to call {@link #obtain Message.obtain()} or one of the
       * {@link Handler#obtainMessage Handler.obtainMessage()} methods, which will pull
       * them from a pool of recycled objects.

       上文的意思是: 虽然message的构造方法是对外开放的(public),但是,我们要获取一个message时候最好使用这个方法obtainMessage(),这个方法可以从一个可以复用的对象池中获取你需要的message.

      同上面的意思,我们可以知道,原来message内其实维护了一个对象池,当我们使用完一个message的时候,这个message很有可能就会保存在这个对象池里面,也就是说message里面有一个对象池来保存我们使用过的message.实际上,通过代码,我们可以知道当对象池里面没有我们需要的message时候,会自动new 一个message的. 所以不必担心obtainMessage()获取不了message.

     现在来看看android的message的对象池时如何设计的.实际上,message里面的对象池其实是通过维护一个单项链表来实现的!看看下面就知道来.

     在message里面有一下几个变量的声明和定义:

    /*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;
      next 指向下一个可用的message;      

      sPoolSync主要用来同步用的,保证多线程安全;

      Message sPool;这里的sPool用来表示当前一个可用的message,请注意这是一个static修饰的message,

     sPoolSize用来记录当前message对象池有多少个messagel . 

     最后解释一下: message里面其实时维护来一个单项链表结构来保存message对象的!next永来指向下一个message对象,这里的sPool很显然就是这个链表的表头.这样以来就可以通过表头顺序遍历整个对象池里面的message.

    上面我说了,当通过这个方法obtainMessage()来获取一个message时候,就会去对象池里面找取(这里就是去这个单向链表中找取),如果对象池里面没有我们需要的message,就会new一个message. 我们来看看代码来证明我所说的.

    public static Message obtain() {        synchronized (sPoolSync) {            if (sPool != null) {                Message m = sPool;                sPool = m.next;                m.next = null;                sPoolSize--;                return m;            }        }        return new Message();    }
      通过上面的代码可以看出:如果链表不为null,就取链表头的message,然后把链表头部下移动. 否在就会new Message().

      最后要说的是,当一个message用完了后是如何加入这个链表的呢? 通过文件Message.java,你会发现在Message里面还定义来一个public的方法:

    public void recycle() {        clearForRecycle();        synchronized (sPoolSync) {            if (sPoolSize < MAX_POOL_SIZE) {                next = sPool;                sPool = this;                sPoolSize++;            }        }    }
      通过上面的代码可以知道recycle方法其实就是将这个message加入到这个链表(加入到了头部).那么,这个方法时在何时调用的呢?

      实际上,当通过Handler发送一个message的时候,其实是将这个message根据他的延时来决定他的位置,将其添加到一个队列里面的MessageQueue,操作这个MessageQueue不仅仅是这个Handler,还有这个Handler的Looper.

     其实每一个Handler都是需要一个Looper的,往往我们创建一个Handler的时候其实是没有指明他的Looper,不过他会自动获取创建这个Handler的线程的Looper来作为自己的Looper,所以,在android中,往往没有指明Handler的Looper,其实就是用主线程(就是我们常说的ui线程)的Looper.

    刚才我们说了,Handler的Looper其实也操作MessageQueue的,实际上一个Looper就需要一个MessageQueue的,我个人的理解是:Looper的目的就是操作MessageQueue,而Handler控制着Looper和MessageQueue.

   其实时这样的: Handler往MessageQueue里面加入需要处理的message,而Looper从MessageQueue里面取出需要处理的message来开始处理流程.

   在Looper里面其实是通过调用方法loop()来取出需要处理的message,并处理,处理完毕时候就会调用这个message的recycle(),由此来将处理完毕的message加入到对象池的!

更多相关文章

  1. Android(安卓)后台保活,这里有你需要的所有姿势。2019,最新版本。
  2. Android(安卓)五大布局FrameLayout,LinearLayout ,AbsoluteLayou
  3. Android(安卓)gallery实现图片的左右循环旋转源码分享
  4. android ndk 使用第三方静态库
  5. SharedPreferences之Android数据保存
  6. Android中调试获取Log
  7. Android的绘制文本对象FontMetrics的介绍及绘制文本
  8. android中Pull解析器
  9. Android(安卓)market 发布个人免费应用的步骤

随机推荐

  1. android中SqLite query中用selectionArgs
  2. Android(安卓)手机配office365邮箱
  3. Android之实现textvew跑马灯效果
  4. android 分辨率及密度详细
  5. android下的多媒体开源项目
  6. Android学习笔记_79_ Android(安卓)使用
  7. android studio的问题整理
  8. 我是新手,我在学Android
  9. Android(安卓)tabhost让选中项加上背景图
  10. 分享20个Android游戏源码,希望大家喜欢哈!