ResourceRunner.java revision da7bc32c1a0d448f7d29685692a45eb5f6867fa5
1package com.bumptech.glide.load.engine; 2 3import android.os.Handler; 4import android.os.SystemClock; 5import android.util.Log; 6import com.bumptech.glide.Resource; 7import com.bumptech.glide.load.Key; 8import com.bumptech.glide.load.ResourceDecoder; 9import com.bumptech.glide.load.Transformation; 10import com.bumptech.glide.load.engine.cache.DiskCache; 11import com.bumptech.glide.load.resource.transcode.ResourceTranscoder; 12 13import java.io.IOException; 14import java.io.InputStream; 15import java.util.concurrent.ExecutorService; 16import java.util.concurrent.Future; 17 18/** 19 * 20 * @param <Z> The type of the resource that will be decoded. 21 * @param <R> the type of the resource the decoded resource will be transcoded to. 22 */ 23public class ResourceRunner<Z, R> implements Runnable { 24 private static final String TAG = "ResourceRunner"; 25 26 private final Key key; 27 private Transformation<Z> transformation; 28 private ResourceTranscoder<Z, R> transcoder; 29 private final SourceResourceRunner sourceRunner; 30 private final ExecutorService executorService; 31 private final EngineJob job; 32 private final ResourceDecoder<InputStream, Z> cacheDecoder; 33 private final int width; 34 private final int height; 35 private final DiskCache diskCache; 36 private final Handler bgHandler; 37 private volatile Future<?> future; 38 private volatile boolean isCancelled; 39 40 public ResourceRunner(Key key, int width, int height, DiskCache diskCache, 41 ResourceDecoder<InputStream, Z> cacheDecoder, Transformation<Z> transformation, 42 ResourceTranscoder<Z, R> transcoder, SourceResourceRunner sourceRunner, ExecutorService executorService, 43 Handler bgHandler, EngineJob job) { 44 this.key = key; 45 this.width = width; 46 this.height = height; 47 this.diskCache = diskCache; 48 this.cacheDecoder = cacheDecoder; 49 this.transformation = transformation; 50 this.transcoder = transcoder; 51 this.sourceRunner = sourceRunner; 52 this.executorService = executorService; 53 this.bgHandler = bgHandler; 54 this.job = job; 55 } 56 57 public EngineJob getJob() { 58 return job; 59 } 60 61 public void cancel() { 62 isCancelled = true; 63 bgHandler.removeCallbacks(this); 64 if (future != null) { 65 future.cancel(false); 66 } 67 sourceRunner.cancel(); 68 } 69 70 public void queue() { 71 bgHandler.post(this); 72 } 73 74 @Override 75 public void run() { 76 if (isCancelled) { 77 return; 78 } 79 80 long start = SystemClock.currentThreadTimeMillis(); 81 Resource<Z> fromCache = loadFromDiskCache(); 82 if (Log.isLoggable(TAG, Log.VERBOSE)) { 83 Log.v(TAG, "loaded from disk cache in " + (SystemClock.currentThreadTimeMillis() - start)); 84 } 85 if (fromCache != null) { 86 Resource<Z> transformed = transformation.transform(fromCache, width, height); 87 if (transformed != fromCache) { 88 fromCache.recycle(); 89 } 90 Resource<R> transcoded = transcoder.transcode(transformed); 91 job.onResourceReady(transcoded); 92 } else { 93 future = executorService.submit(sourceRunner); 94 } 95 } 96 97 private Resource<Z> loadFromDiskCache() { 98 Resource<Z> result = null; 99 InputStream fromCache = diskCache.get(key); 100 if (fromCache != null) { 101 try { 102 result = cacheDecoder.decode(fromCache, width, height); 103 } catch (IOException e) { 104 if (Log.isLoggable(TAG, Log.DEBUG)) { 105 Log.d(TAG, "Exception decoding image from cache", e); 106 } 107 } 108 if (result == null) { 109 if (Log.isLoggable(TAG, Log.DEBUG)) { 110 Log.d(TAG, "Failed to decode image from cache or not present in cache"); 111 } 112 diskCache.delete(key); 113 } 114 } 115 return result; 116 } 117} 118