【问题标题】:OutOfMemoryError bitmaps androidOutOfMemoryError 位图 android
【发布时间】:2023-03-20 15:36:01
【问题描述】:

我在 android 中缓存我的图像,但不知道如何重用位图,因为 android 在这里建议: https://developer.android.com/training/displaying-bitmaps/manage-memory.html 这是我的代码

final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    // Use 1/8th of the available memory for this memory cache.
    final int cacheSize = maxMemory / 8;
    this.imageCache= new LruCache<String, Bitmap>(cacheSize){


         @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // The cache size will be measured in kilobytes rather than
                // number of items.
                return bitmap.getByteCount() / 1024;
            }

    };
    this.m_adapter = new ImageScreenAdapter(this, R.layout.imagelist_item, items, imageCache);
    setListAdapter(this.m_adapter);

这是我用来下载位图的方法

  private Bitmap downloadBitmap(String url, ProgressBar progress, int position) {
    final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
    final HttpGet getRequest = new HttpGet(url);
    try {
        HttpResponse response = client.execute(getRequest);
        final int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) {
            Log.w("ImageDownloader", "Error " + statusCode
                    + " while retrieving bitmap from " + url);
            if(progress!=null)
            {
              RemoveImageResults(position);
              return null;
            }
            return BitmapFactory.decodeResource(getResources(), R.drawable.missingpic);
        }

        final HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream inputStream = null;
            try {
                inputStream = entity.getContent();
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = false;
                options.inDither = true;
                final Bitmap bitmap = BitmapFactory.decodeStream(inputStream,null, options);
                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);
    } finally {
        if (client != null) {
            client.close();
        }
    }
    return null;
}

在我的 AsyncTask 中

  @Override
   protected void onPostExecute(Bitmap result) {
      final Bitmap Image=result;
       if(Image!=null)
           imageCache.put(imageUrl, Image);
       myActivity.runOnUiThread(new Runnable() {
           public void run() {

               imageView.setImageBitmap(Image);
               imageView.setVisibility(View.VISIBLE);

           }
         });

   }

   private Bitmap download_Image(String url) {
      return downloadBitmap(url, progress, position);


   }

但是,如果它在我的列表适配器中获得多达 1000 个图像,这可能会耗尽内存,那么如何重用位图或回收未使用的位图?我的目标是 android 3.0 或更高版本,正如 android 建议的那样,我可以使用 Set> mReusableBitmaps;但我不知道如何实现这一点。

【问题讨论】:

    标签: java android caching bitmap out-of-memory


    【解决方案1】:

    处理此问题的最佳方法是实现某种延迟图像加载,其中您有弱引用位图,可以更容易地被系统回收。网上有大量的示例,并且 github 上有一个非常流行的开源库可以为您完成所有这些工作。他们甚至有回调,您可以使用这些回调在图像加载时显示进度条,并在图像下载完成时将其删除。你可以在这里找到它:https://github.com/nostra13/Android-Universal-Image-Loader

    【讨论】:

    • 它的工作方式是将图像缓存在设备的硬内存上,然后当它们一段时间没有出现时回收它们,然后它会出去并从设备或互联网上获取它们再次需要图像。
    • 图片是否缓存在设备上的某处?该库具有不同的配置,因此您可以将其设置为将图像保存在设备上,但开箱即用它不会这样做。我很确定您必须告诉它将图像存储在设备上,并且当您不这样做时,默认行为是使用运行时内存,并在默认设置中给出分配的数量,因此您的图像可能会进入并被回收,因为有没有更多空间了。
    • 这似乎很有效,让我继续测试一下
    • 是的,很久以前,当 android 刚出现时,我最终创造了一些非常相似的东西,它非常棒,现在它如此受欢迎,你可以在网上找到开源库和东西,所以你不必重新创建一直在轮子:)
    • 是的,这绝对是要走的路。尝试为我正在进行的一些自定义事情解决一些问题,但仍然非常棒
    猜你喜欢
    • 2013-05-16
    • 1970-01-01
    • 2014-05-28
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2011-10-22
    相关资源
    最近更新 更多