【问题标题】:Bitmap recycling in Android - when and where?Android 中的位图回收 - 何时何地?
【发布时间】:2014-03-05 20:04:24
【问题描述】:

我不确定如何回收位图。

我有一个在列表视图中显示大量项目的应用程序。问题是如果我不降低 ImageDownloader 类中图像的质量,应用程序就会崩溃。

在下面提供的代码中,如果我更改 options.inSampleSize = 4,图像质量会降低,并且应用程序不会耗尽内存。但是,我想使用高质量的图像而不会使我的应用程序崩溃。

我该怎么做?

我的 ImageDownloader 的一部分:

static Bitmap downloadBitmap(String url) {
    HttpParams params = new BasicHttpParams();
    params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
    HttpClient client = new DefaultHttpClient(params);
    final HttpGet getRequest = new HttpGet(url);

    try {
        HttpResponse response = client.execute(getRequest);
        final int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) {
            String[] urlBits = url.split("/");
            Bitmap bitmap = MiscHelpers.getBitmapFromAsset(context, "animals/" + urlBits[urlBits.length-2] + ".jpg");
            Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url);
            return bitmap;
        }

        final HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream inputStream = null;
            try {
                inputStream = entity.getContent();
                BitmapFactory.Options options=new BitmapFactory.Options();
                options.inSampleSize = 1;


                final Bitmap bitmap = BitmapFactory.decodeStream(inputStream,null,options);
                //final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

                return bitmap;
            } finally {
                if (inputStream != null) {
                    inputStream.close();  
                }
                entity.consumeContent();
            }
        }
    } catch (Exception e) {
        // Could provide a more explicit error message for IOException or IllegalStateException
        getRequest.abort();
        Log.w("ImageDownloader", "Error while retrieving bitmap from " + url + e.toString());
    } finally {
        if (client != null) {
            //client.close();
        }
    }
    return null;
}

我的 ListView 适配器:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    // Inflate the layout
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.list_single, parent, false);

    ImageView image = (ImageView) rowView.findViewById(R.id.picture);
    TextView firstline = (TextView) rowView.findViewById(R.id.firstline);
    TextView secondline = (TextView) rowView.findViewById(R.id.secondline);         

    // Get information about the report
    AnimalLocationLog current = objects.get(position);

    // Get all the important information
    String species = current.getSpecies();
    String sanitizedSpecies = MiscHelpers.sanitizeString(species);
    int reportId = objects.get(position).getTrackerId();

    // Construct the URL to the image
    String imageLocation = websiteUrl + sanitizedSpecies + separator + reportId + extension;

    // Display user report          
    downloader.download(imageLocation, image);          
    firstline.setText(species);
    secondline.setText("Spotted " + current.getDateTime().toString("yyyy-MM-dd H:m"));          

    urlToPath = downloader.getUrlToPath();

    return rowView;
}

【问题讨论】:

  • 使用 ViewHolder 模式是一种很好的做法。此外,您应该在后台加载图像(downloader.download 方法)。然后,您可以修改此方法以接收 imageView,并且可以在设置新的位图之前回收以前的位图。值得一读:developer.android.com/training/displaying-bitmaps/…(如果你还没有的话)。

标签: android android-listview bitmap listviewitem android-bitmap


【解决方案1】:

我看不出有什么明显的错误。也许在图像编辑方面可以做一些事情来使图像更小?

我建议进行堆转储并将其加载到 Eclipse MAT,https://www.eclipse.org/mat/,以全面了解正在发生的事情。我特别推荐查看 Dominators 报告。

【讨论】:

  • 嗨,马特,谢谢您的回答。我可以将图像缩小,但是,我仍然需要回收位图,不是吗?
  • 我不确定是否有必要回收位图。根据本指南,仅提及 Gingerbread 及更低级别的回收,developer.android.com/training/displaying-bitmaps/…。如果您确实想尝试回收位图,则应遵循该文章中的建议“仅当您确定不再使用位图时才应使用 recycle()。如果您调用 recycle() 并稍后尝试绘制位图,你会得到错误:“画布:试图使用回收的位图”。”
猜你喜欢
  • 2012-08-09
  • 2011-04-18
  • 2011-12-22
  • 2012-10-26
  • 1970-01-01
  • 2012-07-20
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
相关资源
最近更新 更多