1package com.bumptech.glide.load.engine; 2 3import android.os.SystemClock; 4import android.util.Log; 5import com.bumptech.glide.load.CacheLoader; 6import com.bumptech.glide.Priority; 7import com.bumptech.glide.load.ResourceDecoder; 8import com.bumptech.glide.load.Transformation; 9import com.bumptech.glide.load.engine.executor.Prioritized; 10import com.bumptech.glide.load.resource.transcode.ResourceTranscoder; 11 12import java.io.InputStream; 13import java.util.concurrent.ExecutorService; 14import java.util.concurrent.Future; 15 16/** 17 * 18 * @param <Z> The type of the resource that will be decoded. 19 * @param <R> the type of the resource the decoded resource will be transcoded to. 20 */ 21public class ResourceRunner<Z, R> implements Runnable, Prioritized { 22 private static final String TAG = "ResourceRunner"; 23 24 private final EngineKey key; 25 private final Transformation<Z> transformation; 26 private final ResourceTranscoder<Z, R> transcoder; 27 private final SourceResourceRunner sourceRunner; 28 private final EngineJob job; 29 private final Priority priority; 30 private final ResourceDecoder<InputStream, Z> cacheDecoder; 31 private final int width; 32 private final int height; 33 private final CacheLoader cacheLoader; 34 private final ExecutorService diskCacheService; 35 private final ExecutorService resizeService; 36 private volatile Future<?> future; 37 private volatile boolean isCancelled; 38 39 public ResourceRunner(EngineKey key, int width, int height, CacheLoader cacheLoader, 40 ResourceDecoder<InputStream, Z> cacheDecoder, Transformation<Z> transformation, 41 ResourceTranscoder<Z, R> transcoder, SourceResourceRunner sourceRunner, ExecutorService diskCacheService, 42 ExecutorService resizeService, EngineJob job, Priority priority) { 43 this.key = key; 44 this.width = width; 45 this.height = height; 46 this.cacheLoader = cacheLoader; 47 this.cacheDecoder = cacheDecoder; 48 this.transformation = transformation; 49 this.transcoder = transcoder; 50 this.sourceRunner = sourceRunner; 51 this.diskCacheService = diskCacheService; 52 this.resizeService = resizeService; 53 this.job = job; 54 this.priority = priority; 55 } 56 57 public EngineJob getJob() { 58 return job; 59 } 60 61 public void cancel() { 62 isCancelled = true; 63 if (future != null) { 64 future.cancel(false); 65 } 66 sourceRunner.cancel(); 67 } 68 69 public void queue() { 70 future = diskCacheService.submit(this); 71 } 72 73 @Override 74 public void run() { 75 if (isCancelled) { 76 return; 77 } 78 79 long start = SystemClock.currentThreadTimeMillis(); 80 Resource<Z> fromCache = cacheLoader.load(key, cacheDecoder, width, height); 81 if (Log.isLoggable(TAG, Log.VERBOSE)) { 82 Log.v(TAG, "loaded from disk cache in " + (SystemClock.currentThreadTimeMillis() - start)); 83 } 84 if (fromCache != null) { 85 Resource<Z> transformed = transformation.transform(fromCache, width, height); 86 if (transformed != fromCache) { 87 fromCache.recycle(); 88 } 89 Resource<R> transcoded = transcoder.transcode(transformed); 90 job.onResourceReady(transcoded); 91 } else { 92 future = resizeService.submit(sourceRunner); 93 } 94 } 95 96 @Override 97 public int getPriority() { 98 return priority.ordinal(); 99 } 100} 101