Skip to content

Commit

Permalink
Issue #150 - Pass auxiliary Object to Display Options for
Browse files Browse the repository at this point in the history
ImageDownloader
Refactored ImageDownloaders: made ImageDownloder as interface, created
BaseImageDownloader as default implementation
  • Loading branch information
nostra13 committed Feb 8, 2013
1 parent b7223d3 commit d279cb1
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 165 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import com.nostra13.universalimageloader.core.assist.MemoryCacheUtil;
import com.nostra13.universalimageloader.core.display.BitmapDisplayer;
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
import com.nostra13.universalimageloader.core.download.ExtendedImageDownloader;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import com.nostra13.universalimageloader.core.download.ImageDownloader;
import com.nostra13.universalimageloader.utils.StorageUtils;

Expand Down Expand Up @@ -56,9 +56,9 @@ public static MemoryCacheAware<String, Bitmap> createMemoryCache(int memoryCache
return memoryCache;
}

/** Create default implementation of {@link ImageDownloader} - {@link ExtendedImageDownloader} */
/** Create default implementation of {@link ImageDownloader} - {@link BaseImageDownloader} */
public static ImageDownloader createImageDownloader(Context context) {
return new ExtendedImageDownloader(context);
return new BaseImageDownloader(context);
}

/** Create default implementation of {@link BitmapDisplayer} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.display.BitmapDisplayer;
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
import com.nostra13.universalimageloader.core.download.ImageDownloader;
import com.nostra13.universalimageloader.core.process.BitmapProcessor;

/**
Expand Down Expand Up @@ -44,6 +45,7 @@ public final class DisplayImageOptions {
private final ImageScaleType imageScaleType;
private final Bitmap.Config bitmapConfig;
private final int delayBeforeLoading;
private final Object extraForDownloader;
private final BitmapProcessor preProcessor;
private final BitmapProcessor postProcessor;
private final BitmapDisplayer displayer;
Expand All @@ -58,6 +60,7 @@ private DisplayImageOptions(Builder builder) {
imageScaleType = builder.imageScaleType;
bitmapConfig = builder.bitmapConfig;
delayBeforeLoading = builder.delayBeforeLoading;
extraForDownloader = builder.extraForDownloader;
preProcessor = builder.preProcessor;
postProcessor = builder.postProcessor;
displayer = builder.displayer;
Expand Down Expand Up @@ -123,6 +126,10 @@ int getDelayBeforeLoading() {
return delayBeforeLoading;
}

Object getExtraForDownloader() {
return extraForDownloader;
}

BitmapProcessor getPreProcessor() {
return preProcessor;
}
Expand Down Expand Up @@ -150,6 +157,7 @@ public static class Builder {
private ImageScaleType imageScaleType = ImageScaleType.IN_SAMPLE_POWER_OF_2;
private Bitmap.Config bitmapConfig = Bitmap.Config.ARGB_8888;
private int delayBeforeLoading = 0;
private Object extraForDownloader = null;
private BitmapProcessor preProcessor = null;
private BitmapProcessor postProcessor = null;
private BitmapDisplayer displayer = DefaultConfigurationFactory.createBitmapDisplayer();
Expand Down Expand Up @@ -225,6 +233,12 @@ public Builder delayBeforeLoading(int delayInMillis) {
return this;
}

/** Sets auxiliary object which will be passed to {@link ImageDownloader#getStream(java.net.URI, Object)} */
public Builder extraForDownloader(Object extra) {
this.extraForDownloader = extra;
return this;
}

/**
* Sets bitmap processor which will be process bitmaps before they will be cached in memory. So memory cache
* will contain bitmap processed by incoming preProcessor.<br />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public Bitmap decode(ImageSize targetSize, ImageScaleType scaleType) throws IOEx
*/
public Bitmap decode(ImageSize targetSize, ImageScaleType scaleType, ViewScaleType viewScaleType) throws IOException {
Options decodeOptions = getBitmapOptionsForImageDecoding(targetSize, scaleType, viewScaleType);
InputStream imageStream = imageDownloader.getStream(imageUri);
InputStream imageStream = imageDownloader.getStream(imageUri, displayOptions.getExtraForDownloader());
Bitmap subsampledBitmap;
try {
subsampledBitmap = BitmapFactory.decodeStream(imageStream, null, decodeOptions);
Expand Down Expand Up @@ -109,7 +109,7 @@ private int computeImageScale(ImageSize targetSize, ImageScaleType scaleType, Vi
// decode image size
Options options = new Options();
options.inJustDecodeBounds = true;
InputStream imageStream = imageDownloader.getStream(imageUri);
InputStream imageStream = imageDownloader.getStream(imageUri, displayOptions.getExtraForDownloader());
try {
BitmapFactory.decodeStream(imageStream, null, options);
} finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ public Thread newThread(Runnable r) {
* <li>memoryCache = {@link UsingFreqLimitedCache} with limited memory cache size (
* {@link Builder#DEFAULT_MEMORY_CACHE_SIZE this} bytes)</li>
* <li>discCache = {@link UnlimitedDiscCache}</li>
* <li>imageDownloader = {@link ImageDownloader#createDefault()}</li>
* <li>discCacheFileNameGenerator = {@link FileNameGenerator#createDefault()}</li>
* <li>imageDownloader = {@link DefaultConfigurationFactory#createImageDownloader(Context)}</li>
* <li>discCacheFileNameGenerator = {@link DefaultConfigurationFactory#createFileNameGenerator()}</li>
* <li>defaultDisplayImageOptions = {@link DisplayImageOptions#createSimple() Simple options}</li>
* <li>tasksProcessingOrder = {@link QueueProcessingType#FIFO}</li>
* <li>detailed logging disabled</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ private void saveImageOnDisc(File targetFile) throws IOException, URISyntaxExcep

// If previous compression wasn't needed or failed
// Download and save original image
InputStream is = downloader.getStream(new URI(uri));
InputStream is = downloader.getStream(new URI(uri), options.getExtraForDownloader());
try {
OutputStream os = new BufferedOutputStream(new FileOutputStream(targetFile), BUFFER_SIZE);
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package com.nostra13.universalimageloader.core.download;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URLConnection;

import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.assist.FlushedInputStream;

/**
* Provides retrieving of {@link InputStream} of image by URI from network or file system or app resources.<br />
* {@link URLConnection} is used to retrieve image stream from network.
*
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
*
* @see HttpClientImageDownloader
*/
public class BaseImageDownloader implements ImageDownloader {

/** {@value} */
public static final int DEFAULT_HTTP_CONNECT_TIMEOUT = 5 * 1000; // milliseconds
/** {@value} */
public static final int DEFAULT_HTTP_READ_TIMEOUT = 20 * 1000; // milliseconds

protected static final int BUFFER_SIZE = 8 * 1024; // 8 Kb

protected static final String SCHEME_HTTP = "http";
protected static final String SCHEME_HTTPS = "https";
protected static final String SCHEME_FILE = "file";
protected static final String SCHEME_CONTENT = "content";
protected static final String SCHEME_ASSETS = "assets";
protected static final String SCHEME_DRAWABLE = "drawable";

protected static final String SCHEME_ASSETS_PREFIX = SCHEME_ASSETS + "://";
protected static final String SCHEME_DRAWABLE_PREFIX = SCHEME_DRAWABLE + "://";

protected final Context context;
protected final int connectTimeout;
protected final int readTimeout;

public BaseImageDownloader(Context context) {
this.context = context.getApplicationContext();
this.connectTimeout = DEFAULT_HTTP_CONNECT_TIMEOUT;
this.readTimeout = DEFAULT_HTTP_READ_TIMEOUT;
}

public BaseImageDownloader(Context context, int connectTimeout, int readTimeout) {
this.context = context.getApplicationContext();
this.connectTimeout = connectTimeout;
this.readTimeout = readTimeout;
}

@Override
public InputStream getStream(URI imageUri, Object extra) throws IOException {
String scheme = imageUri.getScheme();
if (SCHEME_HTTP.equals(scheme) || SCHEME_HTTPS.equals(scheme)) {
return getStreamFromNetwork(imageUri, extra);
} else if (SCHEME_FILE.equals(scheme)) {
return getStreamFromFile(imageUri, extra);
} else if (SCHEME_CONTENT.equals(scheme)) {
return getStreamFromContent(imageUri, extra);
} else if (SCHEME_ASSETS.equals(scheme)) {
return getStreamFromAssets(imageUri, extra);
} else if (SCHEME_DRAWABLE.equals(scheme)) {
return getStreamFromDrawable(imageUri, extra);
} else {
return getStreamFromOtherSource(imageUri, extra);
}
}

/**
* Retrieves {@link InputStream} of image by URI (image is located in the network).
*
* @param imageUri Image URI
* @param extra Auxiliary object which was passed to {@link DisplayImageOptions.Builder#extraForDownloader(Object)
* DisplayImageOptions.extraForDownloader(Object)}; can be null
* @return {@link InputStream} of image
* @throws IOException if some I/O error occurs during network request or if no InputStream could be created for
* URI.
*/
protected InputStream getStreamFromNetwork(URI imageUri, Object extra) throws IOException {
HttpURLConnection conn = (HttpURLConnection) imageUri.toURL().openConnection();
conn.setConnectTimeout(connectTimeout);
conn.setReadTimeout(readTimeout);
return new FlushedInputStream(conn.getInputStream(), BUFFER_SIZE);
}

/**
* Retrieves {@link InputStream} of image by URI (image is located on the local file system or SD card).
*
* @param imageUri Image URI
* @param extra Auxiliary object which was passed to {@link DisplayImageOptions.Builder#extraForDownloader(Object)
* DisplayImageOptions.extraForDownloader(Object)}; can be null
* @return {@link InputStream} of image
* @throws IOException if some I/O error occurs reading from file system
*/
protected InputStream getStreamFromFile(URI imageUri, Object extra) throws IOException {
return new BufferedInputStream(imageUri.toURL().openStream(), BUFFER_SIZE);
}

/**
* Retrieves {@link InputStream} of image by URI (image is accessed using {@link ContentResolver}).
*
* @param imageUri Image URI
* @param extra Auxiliary object which was passed to {@link DisplayImageOptions.Builder#extraForDownloader(Object)
* DisplayImageOptions.extraForDownloader(Object)}; can be null
* @return {@link InputStream} of image
* @throws FileNotFoundException if the provided URI could not be opened
*/
protected InputStream getStreamFromContent(URI imageUri, Object extra) throws FileNotFoundException {
ContentResolver res = context.getContentResolver();
Uri uri = Uri.parse(imageUri.toString());
return res.openInputStream(uri);
}

/**
* Retrieves {@link InputStream} of image by URI (image is located in assets of application).
*
* @param imageUri Image URI
* @param extra Auxiliary object which was passed to {@link DisplayImageOptions.Builder#extraForDownloader(Object)
* DisplayImageOptions.extraForDownloader(Object)}; can be null
* @return {@link InputStream} of image
* @throws IOException if some I/O error occurs file reading
*/
protected InputStream getStreamFromAssets(URI imageUri, Object extra) throws IOException {
String filePath = imageUri.toString().substring(SCHEME_ASSETS_PREFIX.length()); // Remove "assets://" prefix from image URI
return context.getAssets().open(filePath);
}

/**
* Retrieves {@link InputStream} of image by URI (image is located in drawable resources of application).
*
* @param imageUri Image URI
* @param extra Auxiliary object which was passed to {@link DisplayImageOptions.Builder#extraForDownloader(Object)
* DisplayImageOptions.extraForDownloader(Object)}; can be null
* @return {@link InputStream} of image
*/
protected InputStream getStreamFromDrawable(URI imageUri, Object extra) {
String drawableIdString = imageUri.toString().substring(SCHEME_DRAWABLE_PREFIX.length()); // Remove "drawable://" prefix from image URI
int drawableId = Integer.parseInt(drawableIdString);
BitmapDrawable drawable = (BitmapDrawable) context.getResources().getDrawable(drawableId);
Bitmap bitmap = drawable.getBitmap();

ByteArrayOutputStream os = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0, os);
return new ByteArrayInputStream(os.toByteArray());
}

/**
* Retrieves {@link InputStream} of image by URI from other source. Should be overriden by successors to implement
* image downloading from special sources.
*
* @param imageUri Image URI
* @param extra Auxiliary object which was passed to {@link DisplayImageOptions.Builder#extraForDownloader(Object)
* DisplayImageOptions.extraForDownloader(Object)}; can be null
* @return {@link InputStream} of image
* @throws IOException if some I/O error occurs
*/
protected InputStream getStreamFromOtherSource(URI imageUri, Object extra) throws IOException {
return null;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,24 @@
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.BufferedHttpEntity;

import android.content.Context;

/**
* Implementation of ImageDownloader which uses {@link HttpClient} for image stream retrieving.
*
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
*/
public class HttpClientImageDownloader extends ImageDownloader {
public class HttpClientImageDownloader extends BaseImageDownloader {

private HttpClient httpClient;

public HttpClientImageDownloader(HttpClient httpClient) {
public HttpClientImageDownloader(Context context, HttpClient httpClient) {
super(context);
this.httpClient = httpClient;
}

@Override
protected InputStream getStreamFromNetwork(URI imageUri) throws IOException {
protected InputStream getStreamFromNetwork(URI imageUri, Object extra) throws IOException {
HttpGet httpRequest = new HttpGet(imageUri.toString());
HttpResponse response = httpClient.execute(httpRequest);
HttpEntity entity = response.getEntity();
Expand Down
Loading

0 comments on commit d279cb1

Please sign in to comment.