FileDocCategorySizeDatePackage
ImageRequest.javaAPI DocAndroid 5.1 API8530Thu Mar 12 22:22:56 GMT 2015com.android.volley.toolbox

ImageRequest

public class ImageRequest extends com.android.volley.Request
A canned request for getting an image at a given URL and calling back with a decoded Bitmap.

Fields Summary
private static final int
IMAGE_TIMEOUT_MS
Socket timeout in milliseconds for image requests
private static final int
IMAGE_MAX_RETRIES
Default number of retries for image requests
private static final float
IMAGE_BACKOFF_MULT
Default backoff multiplier for image requests
private final Response.Listener
mListener
private final android.graphics.Bitmap.Config
mDecodeConfig
private final int
mMaxWidth
private final int
mMaxHeight
private static final Object
sDecodeLock
Decoding lock so that we don't decode more than one image at a time (to avoid OOM's)
Constructors Summary
public ImageRequest(String url, Response.Listener listener, int maxWidth, int maxHeight, android.graphics.Bitmap.Config decodeConfig, Response.ErrorListener errorListener)
Creates a new image request, decoding to a maximum specified width and height. If both width and height are zero, the image will be decoded to its natural size. If one of the two is nonzero, that dimension will be clamped and the other one will be set to preserve the image's aspect ratio. If both width and height are nonzero, the image will be decoded to be fit in the rectangle of dimensions width x height while keeping its aspect ratio.

param
url URL of the image
param
listener Listener to receive the decoded bitmap
param
maxWidth Maximum width to decode this bitmap to, or zero for none
param
maxHeight Maximum height to decode this bitmap to, or zero for none
param
decodeConfig Format to decode the bitmap to
param
errorListener Error listener, or null to ignore errors


                                                                                                                                                               
            
                
        super(Method.GET, url, errorListener);
        setRetryPolicy(
                new DefaultRetryPolicy(IMAGE_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT));
        mListener = listener;
        mDecodeConfig = decodeConfig;
        mMaxWidth = maxWidth;
        mMaxHeight = maxHeight;
    
Methods Summary
protected voiddeliverResponse(android.graphics.Bitmap response)

        mListener.onResponse(response);
    
private com.android.volley.ResponsedoParse(com.android.volley.NetworkResponse response)
The real guts of parseNetworkResponse. Broken out for readability.

        byte[] data = response.data;
        BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
        Bitmap bitmap = null;
        if (mMaxWidth == 0 && mMaxHeight == 0) {
            decodeOptions.inPreferredConfig = mDecodeConfig;
            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
        } else {
            // If we have to resize this image, first get the natural bounds.
            decodeOptions.inJustDecodeBounds = true;
            BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
            int actualWidth = decodeOptions.outWidth;
            int actualHeight = decodeOptions.outHeight;

            // Then compute the dimensions we would ideally like to decode to.
            int desiredWidth = getResizedDimension(mMaxWidth, mMaxHeight,
                    actualWidth, actualHeight);
            int desiredHeight = getResizedDimension(mMaxHeight, mMaxWidth,
                    actualHeight, actualWidth);

            // Decode to the nearest power of two scaling factor.
            decodeOptions.inJustDecodeBounds = false;
            // TODO(ficus): Do we need this or is it okay since API 8 doesn't support it?
            // decodeOptions.inPreferQualityOverSpeed = PREFER_QUALITY_OVER_SPEED;
            decodeOptions.inSampleSize =
                findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight);
            Bitmap tempBitmap =
                BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);

            // If necessary, scale down to the maximal acceptable size.
            if (tempBitmap != null && (tempBitmap.getWidth() > desiredWidth ||
                    tempBitmap.getHeight() > desiredHeight)) {
                bitmap = Bitmap.createScaledBitmap(tempBitmap,
                        desiredWidth, desiredHeight, true);
                tempBitmap.recycle();
            } else {
                bitmap = tempBitmap;
            }
        }

        if (bitmap == null) {
            return Response.error(new ParseError(response));
        } else {
            return Response.success(bitmap, HttpHeaderParser.parseCacheHeaders(response));
        }
    
static intfindBestSampleSize(int actualWidth, int actualHeight, int desiredWidth, int desiredHeight)
Returns the largest power-of-two divisor for use in downscaling a bitmap that will not result in the scaling past the desired dimensions.

param
actualWidth Actual width of the bitmap
param
actualHeight Actual height of the bitmap
param
desiredWidth Desired width of the bitmap
param
desiredHeight Desired height of the bitmap

        double wr = (double) actualWidth / desiredWidth;
        double hr = (double) actualHeight / desiredHeight;
        double ratio = Math.min(wr, hr);
        float n = 1.0f;
        while ((n * 2) <= ratio) {
            n *= 2;
        }

        return (int) n;
    
public PrioritygetPriority()

        return Priority.LOW;
    
private static intgetResizedDimension(int maxPrimary, int maxSecondary, int actualPrimary, int actualSecondary)
Scales one side of a rectangle to fit aspect ratio.

param
maxPrimary Maximum size of the primary dimension (i.e. width for max width), or zero to maintain aspect ratio with secondary dimension
param
maxSecondary Maximum size of the secondary dimension, or zero to maintain aspect ratio with primary dimension
param
actualPrimary Actual size of the primary dimension
param
actualSecondary Actual size of the secondary dimension

        // If no dominant value at all, just return the actual.
        if (maxPrimary == 0 && maxSecondary == 0) {
            return actualPrimary;
        }

        // If primary is unspecified, scale primary to match secondary's scaling ratio.
        if (maxPrimary == 0) {
            double ratio = (double) maxSecondary / (double) actualSecondary;
            return (int) (actualPrimary * ratio);
        }

        if (maxSecondary == 0) {
            return maxPrimary;
        }

        double ratio = (double) actualSecondary / (double) actualPrimary;
        int resized = maxPrimary;
        if (resized * ratio > maxSecondary) {
            resized = (int) (maxSecondary / ratio);
        }
        return resized;
    
protected com.android.volley.ResponseparseNetworkResponse(com.android.volley.NetworkResponse response)

        // Serialize all decode on a global lock to reduce concurrent heap usage.
        synchronized (sDecodeLock) {
            try {
                return doParse(response);
            } catch (OutOfMemoryError e) {
                VolleyLog.e("Caught OOM for %d byte image, url=%s", response.data.length, getUrl());
                return Response.error(new ParseError(e));
            }
        }