前言
在閱讀Glide源碼時(shí),發(fā)現(xiàn)Glide大量使用對(duì)象池Pools來(lái)對(duì)頻繁需要?jiǎng)?chuàng)建和銷(xiāo)毀的代碼進(jìn)行優(yōu)化丑孩。
比如Glide中冀宴,每個(gè)圖片請(qǐng)求任務(wù),都需要用到 EngineJob 温学、DecodeJob類(lèi)略贮。若每次都需要重新new這些類(lèi),并不是很合適仗岖。而且在大量圖片請(qǐng)求時(shí)逃延,頻繁創(chuàng)建和銷(xiāo)毀這些類(lèi),可能會(huì)導(dǎo)致內(nèi)存抖動(dòng)轧拄,影響性能揽祥。
Glide使用對(duì)象池的機(jī)制,對(duì)這種頻繁需要?jiǎng)?chuàng)建和銷(xiāo)毀的對(duì)象保存在一個(gè)對(duì)象池中檩电。每次用到該對(duì)象時(shí)拄丰,就取對(duì)象池空閑的對(duì)象,并對(duì)它進(jìn)行初始化操作俐末,從而提高框架的性能料按。
代碼介紹
1. 用到的類(lèi)
android.support.v4.util.Pool
2. Pool接口類(lèi)
acquire(): 從對(duì)象池請(qǐng)求對(duì)象的函數(shù):
release(): 釋放對(duì)象回對(duì)象池的函數(shù)
public static interface Pool<T> {
public T acquire();
public boolean release(T instance);
}
3. Android官方對(duì)象池的簡(jiǎn)單實(shí)現(xiàn):SimplePool,也是用得最多的實(shí)現(xiàn)
原理:使用了“懶加載”的思想卓箫。當(dāng)SimplePool初始化時(shí)载矿,不會(huì)生成N個(gè)T類(lèi)型的對(duì)象存放在對(duì)象池中。而是當(dāng)每次外部調(diào)用release()時(shí)丽柿,才把釋放的T類(lèi)型對(duì)象存放在對(duì)象池中恢准。要先放入,才能取出來(lái)甫题。
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. 對(duì)SynchronizedPool的簡(jiǎn)單封裝
由于對(duì)象池設(shè)計(jì)是要先放入馁筐,才能取出來(lái)。所以當(dāng)沒(méi)有放入對(duì)象時(shí)坠非,調(diào)用acquire()敏沉,返回都是null,所以可以對(duì) 對(duì)象池進(jìn)行以下封裝炎码,方便其使用:
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);
}
}