代码优化Android知识Android开发

使用对象池Pools,优化频繁创建和销毁的代码

2017-02-16  本文已影响409人  InKenKa

前言

在阅读Glide源码时,发现Glide大量使用对象池Pools来对频繁需要创建和销毁的代码进行优化。

比如Glide中,每个图片请求任务,都需要用到 EngineJob 、DecodeJob类。若每次都需要重新new这些类,并不是很合适。而且在大量图片请求时,频繁创建和销毁这些类,可能会导致内存抖动,影响性能。

Glide使用对象池的机制,对这种频繁需要创建和销毁的对象保存在一个对象池中。每次用到该对象时,就取对象池空闲的对象,并对它进行初始化操作,从而提高框架的性能。


代码介绍

1. 用到的类
android.support.v4.util.Pool

2. Pool接口类
acquire(): 从对象池请求对象的函数:
release(): 释放对象回对象池的函数

public static interface Pool<T> {

    public T acquire();
    
    public boolean release(T instance);
}

3. Android官方对象池的简单实现:SimplePool,也是用得最多的实现
原理:使用了“懒加载”的思想。当SimplePool初始化时,不会生成N个T类型的对象存放在对象池中。而是当每次外部调用release()时,才把释放的T类型对象存放在对象池中。要先放入,才能取出来。

public static class SimplePool<T> implements Pool<T> {
    private final Object[] mPool;
    private int mPoolSize;
    
    public SimplePool(int maxPoolSize) {
        if (maxPoolSize <= 0) {
            throw new IllegalArgumentException("The max pool size must be > 0");
        }
        mPool = new Object[maxPoolSize];
    }

    @Override
    @SuppressWarnings("unchecked")
    public T acquire() {
        if (mPoolSize > 0) {
            final int lastPooledIndex = mPoolSize - 1;
            T instance = (T) mPool[lastPooledIndex];
            mPool[lastPooledIndex] = null;
            mPoolSize--;
            return instance;
        }
        return null;
    }

    @Override
    public boolean release(T instance) {
        if (isInPool(instance)) {
            throw new IllegalStateException("Already in the pool!");
        }
        if (mPoolSize < mPool.length) {
            mPool[mPoolSize] = instance;
            mPoolSize++;
            return true;
        }
        return false;
    }

    private boolean isInPool(T instance) {
        for (int i = 0; i < mPoolSize; i++) {
            if (mPool[i] == instance) {
                return true;
            }
        }
        return false;
    }
}

4. 对SynchronizedPool的简单封装
由于对象池设计是要先放入,才能取出来。所以当没有放入对象时,调用acquire(),返回都是null,所以可以对 对象池进行以下封装,方便其使用:

public class MyPooledClass {
  private static final SynchronizedPool<MyPooledClass> sPool =
          new SynchronizedPool<MyPooledClass>(10);

  public static MyPooledClass obtain() {
      MyPooledClass instance = sPool.acquire();
      return (instance != null) ? instance : new MyPooledClass();
  }

  public void recycle() {
      sPool.release(this);
  }
}
上一篇下一篇

猜你喜欢

热点阅读