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