Android:调用AsyncTask.execute()会崩溃应用

时间:2015-06-06 11:31:01

标签: android bitmap android-asynctask

我有一个活动,我从给定的URI加载图像。 Android培训文章建议它应该在后台完成,这样它就不会阻止UI。我遵循了相同的Article.

以下是我调用AsyncTask

的代码段
    Uri uri = ....
    ImageLoaderTask task = new ImageLoaderTask(imageView);
    task.execute(uri);

我的ImageLoaderTask如下所示。

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);
            }
        }
}

}

这几乎与上面指定的文章中描述的一样。

ImageUtils类中的代码如下所示

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;
}

当我调用task.execute(uri)时,应用程序崩溃了。我在手机中试了一下,而不是在模拟器上试了一下。我无法让我的模拟器在我的机器上运行,因为它需要太多时间。

可能的原因是什么?

2 个答案:

答案 0 :(得分:1)

不要将ImaageView引用传递给Async类标准实践,而是尝试为加载位图定义自定义接口

public interface ImageBitampLoadListener {
    public void onBitampLoad(Bitmap bitmap);
}

传递自定义界面参考Async

private ImageBitmapLoadListener listener;

public ImageLoaderTask(ImageBitmapLoadListener listener) {
    this.listener = listener;
}

Async设置回叫:

@Override
protected void onPostExecute(Bitmap bitmap) {
   super.onPostExecute(bitmap);
   if(listener!=null){
      listener.onBitampLoad(bitmap);
   }
}

将自定义监听器设置为Async并获取Bitamp

ImageLoaderTask task = new ImageLoaderTask(new ImageBitmapLoadListener() {
    @Override
    public void onBitampLoad(Bitmap bitmap) {
         imageView.setImageBitmap(bitmap);
    }
});
task.execute(uri);

答案 1 :(得分:0)

我通过覆盖AsyncTask的onProgressUpdate()方法解决了这个问题。现在我的ImageLoader代码看起来像

=SUM(
COUNTIF(B5:B32,"*")*5,
COUNTIF(C5:C32,"*")*5,
COUNTIF(D5:D32,"*")*10,
COUNTIF(F5:F32,"*")*20)