Skip to content

Commit

Permalink
Synchronous StreamOpener -> Async StreamLoader
Browse files Browse the repository at this point in the history
An extensive but relatively minor change to the
internal interfaces to allow for asynchronous 
InputStream opening in the ImageManager. This
allows us to use async http libraries (like 
Volley) without forcing us to always start a 
download and then check the ImageManager cache
only after the download completes.
  • Loading branch information
Sam Judd committed Jul 19, 2013
1 parent c02e315 commit e13dced
Show file tree
Hide file tree
Showing 25 changed files with 402 additions and 465 deletions.
55 changes: 28 additions & 27 deletions library/src/com/bumptech/glide/Glide.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import com.bumptech.glide.loader.image.ImageLoader;
import com.bumptech.glide.loader.model.FileStreamLoader;
import com.bumptech.glide.loader.model.ModelStreamLoader;
import com.bumptech.glide.loader.model.UrlStreamLoader;
import com.bumptech.glide.loader.model.FileLoader;
import com.bumptech.glide.loader.model.ModelLoader;
import com.bumptech.glide.loader.model.UrlLoader;
import com.bumptech.glide.presenter.ImagePresenter;
import com.bumptech.glide.presenter.ImageSetCallback;
import com.bumptech.glide.resize.ImageManager;
Expand All @@ -17,8 +17,6 @@

import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
* Static helper methods/classes to present a simple unified interface for using glide. Allows 90%
Expand All @@ -28,17 +26,25 @@
*/
public class Glide {
private static final Glide GLIDE = new Glide();
private static final Map<Class, ModelStreamLoader> classToModelStream = new HashMap<Class, ModelStreamLoader>() {{
put(File.class, new FileStreamLoader());
put(URL.class, new UrlStreamLoader());
}};

private ImageManager imageManager;

public static Glide get() {
return GLIDE;
}

@SuppressWarnings("unchecked")
private static <T> ModelLoader<T> getModelFor(T model) {
if (model == URL.class) {
return (ModelLoader<T>) new UrlLoader();
} else if (model == File.class) {
return (ModelLoader<T>) new FileLoader();
} else {
throw new IllegalArgumentException("No default ModelLoader for class=" + model.getClass() +
", you need to provide one by calling with()");
}
}

protected Glide() { }

/**
Expand Down Expand Up @@ -127,8 +133,9 @@ public static class Request<T> {

private ImagePresenter<T> presenter;
private ImagePresenter.Builder<T> builder;
private ModelStreamLoader<T> modelStreamLoader = null;
private ModelLoader<T> modelLoader = null;

@SuppressWarnings("unchecked")
public Request(T model, ImageView imageView) {
this.model = model;
this.imageView = imageView;
Expand All @@ -138,29 +145,24 @@ public Request(T model, ImageView imageView) {
builder = new ImagePresenter.Builder<T>()
.setImageView(imageView)
.setImageLoader(new Approximate(getImageManager()));

ModelStreamLoader<T> loader = classToModelStream.get(model.getClass());
if (loader != null) {
builder.setModelStreamLoader(loader);
}
}

/**
* Set the {@link ModelStreamLoader} for the model. For URL models, defaults to {@link UrlStreamLoader},
* for File models, defaults to {@link FileStreamLoader}.
* Set the {@link ModelLoader} for the model. For URL models, defaults to {@link UrlLoader},
* for File models, defaults to {@link FileLoader}.
*
* @param modelStreamLoader The {@link ModelStreamLoader} to use. Replaces any existing loader
* @param modelLoader The {@link ModelLoader} to use. Replaces any existing loader
* @return This Request
*/
public Request<T> with(ModelStreamLoader<T> modelStreamLoader) {
this.modelStreamLoader = modelStreamLoader;
builder.setModelStreamLoader(modelStreamLoader);
public Request<T> with(ModelLoader<T> modelLoader) {
this.modelLoader = modelLoader;
builder.setModelLoader(modelLoader);

return this;
}

/**
* Resizes models using {@link ImageManager#centerCrop(String, com.bumptech.glide.loader.opener.StreamOpener, int, int, com.bumptech.glide.resize.LoadedCallback)}
* Resizes models using {@link ImageManager#centerCrop(String, com.bumptech.glide.loader.stream.StreamLoader, int, int, com.bumptech.glide.resize.LoadedCallback)}
* Replaces any existing resize style
*
* @return This Request
Expand All @@ -170,7 +172,7 @@ public Request<T> centerCrop() {
}

/**
* Resizes models using {@link ImageManager#fitCenter(String, com.bumptech.glide.loader.opener.StreamOpener, int, int, com.bumptech.glide.resize.LoadedCallback)}
* Resizes models using {@link ImageManager#fitCenter(String, com.bumptech.glide.loader.stream.StreamLoader, int, int, com.bumptech.glide.resize.LoadedCallback)}
* Replaces any existing resize style
*
* @return This Request
Expand All @@ -180,7 +182,7 @@ public Request<T> fitCenter() {
}

/**
* Resizes models using {@link ImageManager#getImageApproximate(String, com.bumptech.glide.loader.opener.StreamOpener, int, int, com.bumptech.glide.resize.LoadedCallback)}
* Resizes models using {@link ImageManager#getImageApproximate(String, com.bumptech.glide.loader.stream.StreamLoader, int, int, com.bumptech.glide.resize.LoadedCallback)}
* Replaces any existing resize style
*
* @return This Request
Expand Down Expand Up @@ -259,9 +261,8 @@ private ImageManager getImageManager() {
*/
private void build() {
if (presenter == null) {
if (modelStreamLoader == null) {
throw new IllegalArgumentException("You must set a ModelStreamLoader for model class=" +
model.getClass());
if (modelLoader == null) {
modelLoader = getModelFor(model);
}
presenter = builder.build();
imageView.setTag(R.id.image_presenter_id, presenter);
Expand Down
15 changes: 8 additions & 7 deletions library/src/com/bumptech/glide/loader/image/BaseImageLoader.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.bumptech.glide.loader.image;

import android.graphics.Bitmap;
import com.bumptech.glide.loader.opener.StreamOpener;
import com.bumptech.glide.loader.stream.StreamLoader;

import java.lang.ref.WeakReference;

Expand All @@ -12,8 +12,8 @@
*/
public abstract class BaseImageLoader implements ImageLoader {
@Override
public final Object fetchImage(String id, StreamOpener streamOpener, int width, int height, ImageReadyCallback cb) {
doFetchImage(id, streamOpener, width, height, new InternalImageReadyCallback(cb, id));
public final Object fetchImage(String id, StreamLoader streamLoader, int width, int height, ImageReadyCallback cb) {
doFetchImage(id, streamLoader, width, height, new InternalImageReadyCallback(cb, id));
return cb;
}

Expand All @@ -26,15 +26,16 @@ public void clear() { }
* it. Once a load completes or fails the given callback should be called to signal to the calling object that the
* image is ready.
*
* @see ImageLoader#fetchImage(String, com.bumptech.glide.loader.opener.StreamOpener, int, int, com.bumptech.glide.loader.image.ImageLoader.ImageReadyCallback)
* @see ImageLoader#fetchImage(String, com.bumptech.glide.loader.stream.StreamLoader, int, int, com.bumptech.glide.loader.image.ImageLoader.ImageReadyCallback)
*
* @param id A unique id identifying this particular image that will be combined with the provided size info to use as a cache key.
* @param streamOpener The {@link StreamOpener} that will be used to load the image if it is not cached
* @param id A string id that uniquely identifies the image to be loaded. It may include the width and height, but
* is not required to do so
* @param streamLoader The {@link StreamLoader} that will be used to load the image if it is not cached
* @param width The width of the view where the image will be displayed
* @param height The height of the view where the image will be displayed
* @param cb The callback to call when the bitmap is loaded into memory, or when a load fails
*/
protected abstract void doFetchImage(String id, StreamOpener streamOpener, int width, int height, ImageReadyCallback cb);
protected abstract void doFetchImage(String id, StreamLoader streamLoader, int width, int height, ImageReadyCallback cb);

/**
* A lifecycle method called after the requesting object is notified that this loader has loaded a bitmap. Should be
Expand Down
9 changes: 5 additions & 4 deletions library/src/com/bumptech/glide/loader/image/ImageLoader.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.bumptech.glide.loader.image;

import android.graphics.Bitmap;
import com.bumptech.glide.loader.opener.StreamOpener;
import com.bumptech.glide.loader.stream.StreamLoader;

/**
* An interface used by {@link com.bumptech.glide.presenter.ImagePresenter} to fetch a bitmap for a given id and
Expand Down Expand Up @@ -35,15 +35,16 @@ public interface ImageReadyCallback {
/**
* Load the image at the given path represented by the given model
*
* @param id A unique id identifying this particular image that will be combined with the provided size info to use as a cache key.
* @param streamOpener The {@link StreamOpener} that will be used to load the image if it is not cached
* @param id A string id that uniquely identifies the image to be loaded. It may include the width and height, but
* is not required to do so
* @param streamLoader The {@link StreamLoader} that will be used to load the image if it is not cached
* @param width The width of the view where the image will be displayed
* @param height The height of the view where the image will be displayed
* @param cb The callback to call when the bitmap is loaded into memory, or when a load fails
*
* @return A reference to the fetch that must be retained by the calling object as long as the fetch is relevant
*/
public Object fetchImage(String id, StreamOpener streamOpener, int width, int height, ImageReadyCallback cb);
public Object fetchImage(String id, StreamLoader streamLoader, int width, int height, ImageReadyCallback cb);

/**
* Called when the current image load does not need to continue and any corresponding cleanup to save cpu
Expand Down

This file was deleted.

This file was deleted.

26 changes: 26 additions & 0 deletions library/src/com/bumptech/glide/loader/model/FileLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.bumptech.glide.loader.model;

import com.bumptech.glide.loader.stream.FileStreamLoader;
import com.bumptech.glide.loader.stream.StreamLoader;

import java.io.File;

/**
* A simple model loader for {@link File}
*/
public class FileLoader implements ModelLoader<File> {

@Override
public StreamLoader getStreamOpener(File model, int width, int height) {
return new FileStreamLoader(model);
}

@Override
public String getId(File model) {
//canonical is better, but also slower
return model.getAbsolutePath();
}

@Override
public void clear() { }
}
26 changes: 0 additions & 26 deletions library/src/com/bumptech/glide/loader/model/FileStreamLoader.java

This file was deleted.

0 comments on commit e13dced

Please sign in to comment.