I have an activity where I load an image from the given URI. The android training article suggested that it should be done in background so that it does not block the UI. I followed the same Article.
Here is the snippet where I call the AsyncTask
Uri uri = ....
ImageLoaderTask task = new ImageLoaderTask(imageView);
task.execute(uri);
My ImageLoaderTask is given below.
public class ImageLoaderTask extends AsyncTask<Uri, Void, Bitmap> {
private WeakReference<ImageView> imageViewReference;
public ImageLoaderTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
protected Bitmap doInBackground(Uri... params) {
Bitmap bitmap = ImageUtils
.decodeSampledBitmapFromFile(params[0], 200,
200);
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
This is almost as described in the article specified above.
The code in ImageUtils class is given below
public static Bitmap decodeSampledBitmapFromFile(Uri uri,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
File imageFile = getImageFile(uri);
BitmapFactory.decodeFile(imageFile.getPath(), options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(imageFile.getPath(), options);
}
private static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
When I call the task.execute(uri), the app crashes. I tried it in my phone and not on the emulator. I could not get my emulator running on my machine since it takes too much time.
What could be the possible cause of this?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…