package com.bumptech.glide.load.engine;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import com.bumptech.glide.Resource;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
import com.bumptech.glide.load.engine.cache.DiskCache;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
/**
*
* @param <Z> The type of the resource that will be decoded.
* @param <R> the type of the resource the decoded resource will be transcoded to.
*/
public class ResourceRunner<Z, R> implements Runnable {
private static final String TAG = "ResourceRunner";
private final Key key;
private ResourceTranscoder<Z, R> transcoder;
private final SourceResourceRunner sourceRunner;
private final ExecutorService executorService;
private final EngineJob job;
private final ResourceDecoder<InputStream, Z> cacheDecoder;
private final int width;
private final int height;
private final DiskCache diskCache;
private final Handler bgHandler;
private volatile Future<?> future;
private volatile boolean isCancelled;
public ResourceRunner(Key key, int width, int height, DiskCache diskCache,
ResourceDecoder<InputStream, Z> cacheDecoder, ResourceTranscoder<Z, R> transcoder,
SourceResourceRunner sourceRunner, ExecutorService executorService, Handler bgHandler, EngineJob job) {
this.key = key;
this.width = width;
this.height = height;
this.diskCache = diskCache;
this.cacheDecoder = cacheDecoder;
this.transcoder = transcoder;
this.sourceRunner = sourceRunner;
this.executorService = executorService;
this.bgHandler = bgHandler;
this.job = job;
}
public EngineJob getJob() {
return job;
}
public void cancel() {
isCancelled = true;
bgHandler.removeCallbacks(this);
if (future != null) {
future.cancel(false);
}
sourceRunner.cancel();
}
public void queue() {
bgHandler.post(this);
}
@Override
public void run() {
if (isCancelled) {
return;
}
long start = SystemClock.currentThreadTimeMillis();
Resource<Z> fromCache = loadFromDiskCache();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "loaded from disk cache in " + (SystemClock.currentThreadTimeMillis() - start));
}
if (fromCache != null) {
Resource<R> transcoded = transcoder.transcode(fromCache);
job.onResourceReady(transcoded);
} else {
future = executorService.submit(sourceRunner);
}
}
private Resource<Z> loadFromDiskCache() {
Resource<Z> result = null;
InputStream fromCache = diskCache.get(key);
if (fromCache != null) {
try {
result = cacheDecoder.decode(fromCache, width, height);
} catch (IOException e) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Exception decoding image from cache", e);
}
}
if (result == null) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Failed to decode image from cache or not present in cache");
}
diskCache.delete(key);
}
}
return result;
}
}