簡述:
今天看別人代碼,突然發現一個類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