安卓:调用AsyncTask.execute()崩溃的应用程序 [英] Android: Calling AsyncTask.execute() crashes the app

查看:240
本文介绍了安卓:调用AsyncTask.execute()崩溃的应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我的地方加载从给定的URI的图像的活动。 Android的培训文章建议,应在后台进行,以便它不会阻止用户界面。我遵循同样的 一文。

下面就是我所说的AsyncTask的片段

 开放的URI = ....
    ImageLoaderTask任务=新ImageLoaderTask(ImageView的);
    task.execute(URI);

我ImageLoaderTask如下。

 公共类ImageLoaderTask扩展的AsyncTask<开放的,无效的,位图> {私人的WeakReference< ImageView的> imageViewReference;公共ImageLoaderTask(ImageView的ImageView的){
    //使用的WeakReference,确保ImageView的可以被垃圾收集
    imageViewReference =新的WeakReference< ImageView的>(ImageView的);
}@覆盖
保护位图doInBackground(URI ... PARAMS){
    位图位图= ImageUtils
                由Matchi.com提供回到codeSampledBitmapFromFile(PARAMS [0],200,
                        200);
    返回位图;
}@覆盖
保护无效onPostExecute(位图位图){
    如果(imageViewReference = NULL&放大器;!&安培;!=位图NULL){
            最后ImageView的ImageView的= imageViewReference.get();
            如果(ImageView的!= NULL){
                imageView.setImageBitmap(位图);
            }
        }
}}

这几乎是上面指定的文章中介绍。

在ImageUtils类code以下

给出

 公共静态位图德codeSampledBitmapFromFile(URI URI,
                                                 INT reqWidth,诠释reqHeight){    //首先去code。与inJustDe codeBounds = true来检查尺寸
        最后BitmapFactory.Options选项=新BitmapFactory.Options();
        options.inJustDe codeBounds = TRUE;
        文件镜像文件= getImageFile(URI);
        BitmapFactory.de codeFILE(imageFile.getPath(),选件);        //计算inSampleSize
        options.inSampleSize = calculateInSampleSize(选项,reqWidth,reqHeight);        //德code位与inSampleSize集
        options.inJustDe codeBounds = FALSE;
        返回BitmapFactory.de codeFILE(imageFile.getPath(),选件);}私有静态诠释calculateInSampleSize(
        BitmapFactory.Options选项,诠释reqWidth,诠释reqHeight){
    //原始高度和图像宽度
    最终诠释身高= options.outHeight;
    最终诠释宽度= options.outWidth;
    INT inSampleSize = 1;    如果(高度> reqHeight ||宽度GT; reqWidth){        最终诠释halfHeight =身高/ 2;
        最终诠释半宽度=宽度/ 2;        //计算最大inSampleSize值是2的幂,并保持这两个
        //高度和宽度大于所请求的高度和宽度。
        而((halfHeight / inSampleSize)GT; reqHeight
                &功放;&安培; (半角/ inSampleSize)GT; reqWidth){
            inSampleSize * = 2;
        }
    }    返回inSampleSize;
}

当我打电话task.execute(URI),应用程序崩溃。我想在我的电话,而不是在模拟器上。我不能让我的模拟器在我的机器上运行,因为它需要太多的时间。

有什么能这样做的可能的原因?


解决方案

而不是通过 ImaageView 参照异步的级标准的做法试图定义负载位自定义接口

 公共接口ImageBitampLoadListener {
    公共无效onBitampLoad(位图位图);
}

传递自定义界面参考异步

 私人ImageBitmapLoadListener侦听器;公共ImageLoaderTask(ImageBitmapLoadListener监听){
    this.listener =侦听器;
}

设置从异步回拨

  @覆盖
保护无效onPostExecute(位图位图){
   super.onPostExecute(位图);
   如果(听众!= NULL){
      listener.onBitampLoad(位图);
   }
}

设置自定义监听器异步并获得 Bitamp

  ImageLoaderTask任务=新ImageLoaderTask(新ImageBitmapLoadListener(){
    @覆盖
    公共无效onBitampLoad(位图位图){
         imageView.setImageBitmap(位图);
    }
});
task.execute(URI);

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?

解决方案

Instead of passing ImaageView reference to Async class standard practice try to define custom interface for load bitmap

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

Pass custom interface reference Async :

private ImageBitmapLoadListener listener;

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

Set call back from Async :

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

Set custom listener to Async and get Bitamp :

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

这篇关于安卓:调用AsyncTask.execute()崩溃的应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆