Picasso的引用清理策略
Picasso的缓存是对请求的缓存,通过WeakReference与ReferenceQueue的联合使用来缓存请求,然后
关于ReferenceQueue请看下文的详细介绍
WeakReference与ReferenceQueue联合使用构建java高速缓存
//1.首先通过RequestWeakReference来弱化Action的引用强度
static class RequestWeakReference<M> extends WeakReference<M> {
final Action action; public RequestWeakReference(Action action, M referent, ReferenceQueue<? super M> q) {
super(referent, q);
this.action = action;
}
}
//2.其次通过ReferenceQueue来存放引用
Action(Picasso picasso, T target, Request request, int memoryPolicy, int networkPolicy,
int errorResId, Drawable errorDrawable, String key, Object tag, boolean noFade) {
...
this.target = target == null ?
null : new RequestWeakReference<T>(this, target, picasso.referenceQueue);
...
}
//3.通过Picasso内部的CleanupThread来清理ReferenceQueue中的引用。
@Override
public void run() {
Process.setThreadPriority(THREAD_PRIORITY_BACKGROUND);
while (true) {
try {
// Prior to Android 5.0, even when there is no local variable, the result from
// remove() & obtainMessage() is kept as a stack local variable.
// We're forcing this reference to be cleared and replaced by looping every second
// when there is nothing to do.
// This behavior has been tested and reproduced with heap dumps.
RequestWeakReference<?> remove = (RequestWeakReference<?>) referenceQueue.remove(THREAD_LEAK_CLEANING_MS);
Message message = handler.obtainMessage();
if (remove != null) {
message.what = REQUEST_GCED;
message.obj = remove.action;
handler.sendMessage(message);
} else {
message.recycle();
}
} catch (InterruptedException e) {
break;
} catch (final Exception e) {
handler.post(new Runnable() {
@Override
public void run() {
throw new RuntimeException(e);
}
});
break;
}
}
} |