android.support.v4.util.Pools源码解析

简述:

     今天看别人代码,突然发现一个类pools,然后点进去看发现是在v4包下的一个工具类。官方文档对其介绍比较简单就一句话:  

Helper class for crating pools of objects. 
     对象池存取的辅助类。OK,接下来我们就分析一下源码然后再来研究一下它的使用。

源码分析:

    由于源码不多,所以直接贴出来便于分析:

public final class Pools {

    /**
     * Interface for managing a pool of objects.
     *
     * @param <T> The pooled type.
     */
    public static interface Pool<T> {

        /**
         * @return An instance from the pool if such, null otherwise.
         */
        public T acquire();

        /**
         * Release an instance to the pool.
         *
         * @param instance The instance to release.
         * @return Whether the instance was put in the pool.
         *
         * @throws IllegalStateException If the instance is already in the pool.
         */
        public boolean release(T instance);
    }

    private Pools() {
        /* do nothing - hiding constructor */
    }

    /**
     * Simple (non-synchronized) pool of objects.
     *
     * @param <T> The pooled type.
     */
    public static class SimplePool<T> implements Pool<T> {
        private final Object[] mPool;

        private int mPoolSize;

        /**
         * Creates a new instance.
         *
         * @param maxPoolSize The max pool size.
         *
         * @throws IllegalArgumentException If the max pool size is less than zero.
         */
        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;
        }
    }

    /**
     * Synchronized) pool of objects.
     *
     * @param <T> The pooled type.
     */
    public static class SynchronizedPool<T> extends SimplePool<T> {
        private final Object mLock = new Object();

        /**
         * Creates a new instance.
         *
         * @param maxPoolSize The max pool size.
         *
         * @throws IllegalArgumentException If the max pool size is less than zero.
         */
        public SynchronizedPool(int maxPoolSize) {
            super(maxPoolSize);
        }

        @Override
        public T acquire() {
            synchronized (mLock) {
                return super.acquire();
            }
        }

        @Override
        public boolean release(T element) {
            synchronized (mLock) {
                return super.release(element);
            }
        }
    }
}

从上面的源码中可以看出:这个工具类中包含一个私有的构造方法、一个接口和两个类,下面详细解析一下:

    1、Pools类中仅且仅有一个方法,而且该方法为一个私有的构造方法:于是Pools类不能够直接被使用,只能使用其子类(可以预测其一定而且必须有子类)。

    2、包含一个接口Pool<T>,该接口中包含两个方法:

            T acquire():获取一个T对象。

            boolean release(T element):向对象池中添加一个对象,如果该对象已存在于对象池中,则抛出异常IllegalStateException。返回true表示添加成功,否则失败。

    3、包含两个类:SimplePool<T> 和 SynchronizedPool<T>:

            SimplePool<T>实现了Pool接口:其内部利用一个Object[ ]数组来维护这个对象池。

            SynchronizedPool<T>:其继承于SimplePool,是对SimplePool的进一步封装,简单地说就是对每个方法加了一个同步锁。

    OK,分析就分析到这里,接下来我们来看其使用。

使用说明:

  我们约定接下来的几个例子当中对象池中存储的对象DataSet定义如下:

import java.util.HashMap;

/**
 * @author lizhenya
 * @description 数据集合,支持传递复杂数据
 * @since 12/11/2015
 */
public class DataSet {

    private HashMap<Object, Object> data = new HashMap<Object, Object>();
    private Object reciver;

    public Object getReciver() {
        return reciver;
    }

    public void setReciver(Object reciver) {
        this.reciver = reciver;
    }

    public void put(Object key, Object value) {
        data.put(key, value);
    }

    @SuppressWarnings("unchecked")
    public <T> T get(Class<T> cls, String key) {
        Object obj = data.get(key);
        if (obj != null && (obj.getClass() == cls || cls.isInstance(obj)))
            return (T) obj;

        return null;
    }

    public Object get(String key) {
        return data.get(key);
    }

    public void recycle() {
        reciver = null;
        data.clear();
    }

    public String getString(String key) {
        String result = get(String.class, key);
        return result == null ? null : result;
    }

    public int getInt(String key) {
        Integer result = get(Integer.class, key);
        return result == null ? 0 : result;
    }

    public int getInt(String key, int defaultVal) {
        Integer result = get(Integer.class, key);
        return result == null ? defaultVal : result;
    }

    public float getFloat(String key) {
        Float result = get(Float.class, key);
        return result == null ? 0 : result;
    }

    public float getFloat(String key, float defaultVal) {
        Float result = get(Float.class, key);
        return result == null ? defaultVal : result;
    }

    public long getLong(String key) {
        Long result = get(Long.class, key);
        return result == null ? 0 : result;
    }

    public boolean getBoolean(String key) {
        Boolean result = get(Boolean.class, key);
        return result == null ? false : result;
    }

    public String[] getStringArray(String key) {
        String[] array = get(String[].class, key);
        return array == null ? null : array;
    }
}

    1、使用SimplePool来维护一个对象池

/**
 * @author:lizhenya
 * @Time: 16/10/24
 * @email: [email protected]
 */

public class DataPool extends Pools.SimplePool<DataSet> {


    /**
     * Creates a new instance.
     *
     * @param maxPoolSize The max pool size.
     * @throws IllegalArgumentException If the max pool size is less than zero.
     */
    public DataPool(int maxPoolSize) {
        super(maxPoolSize);
    }

    /**
     * 方法描述:获取DataSet对象
     *
     * @return
     */
    public DataSet get() {
        return acquire() != null ? acquire() : new com.lzy.poolsdemo.DataSet();
    }

    /**
     * 方法描述:判断对象池中是否包含dataSet对象实例
     *
     * @param dataSet DataSet对象
     * @return 如果包含含dataSet对象实例返回true, 如果不包含则将dataset对象实例添加到对象池并返回false
     */
    public boolean obtain(DataSet dataSet) {
        return release(dataSet);
    }

}

2、ListPools

      在SimplePools中对象的维护使用的是数组,数组有个最大的缺点:存储满了后不能自增长。所以既要保证效率又能自增长可以采用ArrayList来维护该对象池,下面我们自定义一个ListPool:

/**
 * @author:lizhenya
 * @Time: 16/10/24
 * @email: [email protected]
 */

public class ListPool<T> implements Pools.Pool<T> {
    /**
     * 同步ArrayList
     **/
    private final List<T> ts;

    public ListPool(int maxPoolSize) {
        ts = Collections.synchronizedList(new ArrayList<T>(maxPoolSize));
    }

    @Override
    public T acquire() {
        if (ts.isEmpty())
            return null;
        return ts.remove(0);
    }

    @Override
    public boolean release(T instance) {
        return ts.add(instance);
    }
}
    使用如下:

/**
 * @author:lizhenya
 * @Time: 16/10/24
 * @email: [email protected]
 */

public class ListDataPools extends ListPool<DataSet> {
    public ListDataPools(int maxPoolSize) {
        super(maxPoolSize);
    }

    public DataSet get() {
        return acquire() == null ? new DataSet() : acquire();
    }

    public boolean obtain(DataSet dataSet) {
        dataSet.recycle();
        return release(dataSet);
    }
}

OK,关于android.support.v4.util.Pools的使用与解析比较简单,到此结束。再有半个小时1024程序员节日就要结束了,对大家也对自己说声“节日快乐”。

源码下载:android.support.v4.utils.Pools使用Demo


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章