1package com.bumptech.glide.load.engine; 2 3import android.os.Looper; 4import com.bumptech.glide.load.Key; 5 6/** 7 * A generic resource that handles reference counting so resources can safely be reused. 8 * <p> 9 * Public methods are non final only to allow for mocking, subclasses must only override abstract methods. 10 * </p> 11 * 12 * @param <Z> The type of resource wrapped by this class. 13 */ 14public abstract class Resource<Z> { 15 private volatile int acquired; 16 private volatile boolean isRecycled; 17 private ResourceListener listener; 18 private Key key; 19 private boolean isCacheable; 20 21 interface ResourceListener { 22 public void onResourceReleased(Key key, Resource resource); 23 } 24 25 public abstract Z get(); 26 27 public abstract int getSize(); 28 29 protected abstract void recycleInternal(); 30 31 void setResourceListener(Key key, ResourceListener listener) { 32 this.key = key; 33 this.listener = listener; 34 } 35 36 void setCacheable(boolean isCacheable) { 37 this.isCacheable = isCacheable; 38 } 39 40 boolean isCacheable() { 41 return isCacheable; 42 } 43 44 public void recycle() { 45 if (acquired > 0) { 46 throw new IllegalStateException("Cannot recycle a resource while it is still acquired"); 47 } 48 if (isRecycled) { 49 throw new IllegalStateException("Cannot recycle a resource that has already been recycled"); 50 } 51 isRecycled = true; 52 recycleInternal(); 53 } 54 55 public void acquire(int times) { 56 if (isRecycled) { 57 throw new IllegalStateException("Cannot acquire a recycled resource"); 58 } 59 if (times <= 0) { 60 throw new IllegalArgumentException("Must acquire a number of times >= 0"); 61 } 62 if (!Looper.getMainLooper().equals(Looper.myLooper())) { 63 throw new IllegalThreadStateException("Must call acquire on the main thread"); 64 } 65 acquired += times; 66 } 67 68 public void release() { 69 if (acquired <= 0) { 70 throw new IllegalStateException("Cannot release a recycled or not yet acquired resource"); 71 } 72 if (!Looper.getMainLooper().equals(Looper.myLooper())) { 73 throw new IllegalThreadStateException("Must call release on the main thread"); 74 } 75 if (--acquired == 0) { 76 listener.onResourceReleased(key, this); 77 } 78 } 79} 80