Android - 使用Bitmap的AsyncTask - OutOfMemoryError

时间:2011-08-08 12:58:50

标签: java android multithreading android-asynctask

  

可能重复:
  OutOfMemory Exception when handling images

我在AsyncTask中创建了一个Bitmap,如下所示:

private WeakReference<Bitmap> myBitmap;
private WeakReference<Bitmap> endResultBitmap;
private ImageView imv;

...

private class SendBitmap extends AsyncTask<Integer, Void, Bitmap> {

public SendBitmap(Bitmap bitmap) {
    myBitmap = new WeakReference<Bitmap>(bitmap);
}

@Override
protected Bitmap doInBackground(Integer... params) {
  Bitmap bm = null;
  bm = getBitmapFromNet(params[0]);

  return bm;
}

然后我想创建Bitmap,接收到的Bitmap会出现两次(一个接一个)

protected void onPostExecute(Bitmap result) {
  endResultBitmap = new WeakReference<Bitmap>(Bitmap.createBitmap(result.getWidth() * 2, result.getHeight(), result.getConf()));

  Canvas canvas = new Canvas(endResultBitmap.get());
  canvas.drawBitmap(result, 0, 0, null);
  canvas.drawBitmap(result, result.getWidth(), 0, null);

  imv.setImageBitmap(endResultBitmap);
}

然后我有了onCancelled()方法:

@Override
protected void onCancelled(Bitmap result) {
  if(endResultBitmap!=null) {
    endResultBitmap.recycle();
    endResultBitmap = null;
  }
}

问题在于,如果我执行几次AsyncTask,那么堆就会变得疯狂。 我按下按钮时执行AsyncTask,但最初我会这样做:

public void onClicked(View v) {

  if(asyncTaskInstance != null) 
    asyncTaskInstance.cancel();

  asynctaskInstance.execute(2);
}

但是再一次,Heap变得疯狂,在某些时候它会因 OutOfMemoryError 而崩溃。

有什么想法吗?我的任务设计中有什么问题吗?

1 个答案:

答案 0 :(得分:1)

Android对应用程序有一些内存限制(如果我没记错的话,则为16 MB),并且该图像在未压缩格式下太大。在this question中进行了一些有趣的讨论。

要解决这个问题,只有两种方法:  1.缩小图像尺寸以减少内存消耗  2.使用NDK以本机代码加载图像。

至1:我不知道你到底想要做什么,也无法判断这是否真的是一个可行的选择。如果是,您可能需要从网上下载图像文件并使用BitmapFactory类打开它。有一些静态函数需要BitmapFactory.Options个对象。使用此Options对象中的inSampleSize可以在加载时将图像大小减小一定的因子(顺便说一下,inSampleSize应该是2的幂)。

To 2。:我上面提到的内存限制不适用于本机代码。因此,您可以加载图像并以本机方式显示。我对此没有任何经验,我只知道这是可能的,但谷歌搜索应该会产生一些结果。