1b7c7c2b2505f996dbda219faeb0d08dc1c9982d7Sam Juddpackage com.bumptech.glide.load.engine; 2e52ac307639fca7a22cd5bc3e05ea423b2e60264Sam Judd 359dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Juddimport android.os.Looper; 4e743a1f03f24e33270f38de883b508d4312a7f69Sam Juddimport com.bumptech.glide.load.Key; 5e52ac307639fca7a22cd5bc3e05ea423b2e60264Sam Judd 659dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd/** 759dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd * A generic resource that handles reference counting so resources can safely be reused. 859dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd * <p> 959dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd * Public methods are non final only to allow for mocking, subclasses must only override abstract methods. 1059dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd * </p> 1159dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd * 12785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd * @param <Z> The type of resource wrapped by this class. 1359dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd */ 14785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Juddpublic abstract class Resource<Z> { 1559dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd private volatile int acquired; 1659dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd private volatile boolean isRecycled; 17e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd private ResourceListener listener; 18e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd private Key key; 19e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd private boolean isCacheable; 20e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd 21b7c7c2b2505f996dbda219faeb0d08dc1c9982d7Sam Judd interface ResourceListener { 22e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd public void onResourceReleased(Key key, Resource resource); 23e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd } 240e605e6c38a673ba792606ce559db054a776f5cdSam Judd 25785dc5ee71beeb3ebd77ea73b313eeaf057ae112Sam Judd public abstract Z get(); 26faacbfc1109f255836b4091f6459976295bba7baSam Judd 2759dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd public abstract int getSize(); 2859dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd 2959dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd protected abstract void recycleInternal(); 3059dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd 31b7c7c2b2505f996dbda219faeb0d08dc1c9982d7Sam Judd void setResourceListener(Key key, ResourceListener listener) { 32e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd this.key = key; 33e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd this.listener = listener; 34e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd } 35e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd 36b7c7c2b2505f996dbda219faeb0d08dc1c9982d7Sam Judd void setCacheable(boolean isCacheable) { 37e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd this.isCacheable = isCacheable; 38e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd } 39e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd 40b7c7c2b2505f996dbda219faeb0d08dc1c9982d7Sam Judd boolean isCacheable() { 41e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd return isCacheable; 42e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd } 43e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd 4459dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd public void recycle() { 4559dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd if (acquired > 0) { 4659dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd throw new IllegalStateException("Cannot recycle a resource while it is still acquired"); 4759dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd } 4859dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd if (isRecycled) { 4959dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd throw new IllegalStateException("Cannot recycle a resource that has already been recycled"); 5059dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd } 5159dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd isRecycled = true; 5259dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd recycleInternal(); 5359dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd } 5459dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd 5559dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd public void acquire(int times) { 5659dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd if (isRecycled) { 5759dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd throw new IllegalStateException("Cannot acquire a recycled resource"); 5859dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd } 5959dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd if (times <= 0) { 6059dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd throw new IllegalArgumentException("Must acquire a number of times >= 0"); 6159dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd } 62e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd if (!Looper.getMainLooper().equals(Looper.myLooper())) { 6359dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd throw new IllegalThreadStateException("Must call acquire on the main thread"); 6459dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd } 6559dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd acquired += times; 6659dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd } 6759dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd 6859dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd public void release() { 6959dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd if (acquired <= 0) { 7059dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd throw new IllegalStateException("Cannot release a recycled or not yet acquired resource"); 7159dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd } 72e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd if (!Looper.getMainLooper().equals(Looper.myLooper())) { 7359dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd throw new IllegalThreadStateException("Must call release on the main thread"); 7459dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd } 7559dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd if (--acquired == 0) { 76e743a1f03f24e33270f38de883b508d4312a7f69Sam Judd listener.onResourceReleased(key, this); 7759dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd } 7859dfe6bccb7a462c6239aaca30ead1f3db47e555Sam Judd } 79e52ac307639fca7a22cd5bc3e05ea423b2e60264Sam Judd} 80