ImageRequestpublic 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_MSSocket timeout in milliseconds for image requests | private static final int | IMAGE_MAX_RETRIESDefault number of retries for image requests | private static final float | IMAGE_BACKOFF_MULTDefault 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 | sDecodeLockDecoding 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.
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 void | deliverResponse(android.graphics.Bitmap response)
mListener.onResponse(response);
| private com.android.volley.Response | doParse(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 int | findBestSampleSize(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.
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 Priority | getPriority()
return Priority.LOW;
| private static int | getResizedDimension(int maxPrimary, int maxSecondary, int actualPrimary, int actualSecondary)Scales one side of a rectangle to fit aspect ratio.
// 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.Response | parseNetworkResponse(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));
}
}
|
|