1

内存问题

因此,我正在编写一个应用程序,该应用程序应该能够分页浏览顶部有一个 640 x 480 大图像和 3 个属于延迟加载的画廊的图像的详细视图。遵循谷歌设计指南,这是他们建议的做法。在由于内存不足而崩溃之前,我可以分页浏览大约 12 - 13 个片段。我认为这个问题有几个罪魁祸首。

1.) 我正在使用 FragmentStatePager。当内存成为问题时,这不应该破坏未被查看的片段吗?这没有发生。我以为是自动的。我该怎么做才能做到这一点?这可能与我的 Fragment 实现方式有关吗?我在 onCreateView 中完成所有活动配置。为了彻底起见,我已经包含了这个来源。普通香草在这里:

public static class MyAdapter extends FragmentStatePagerAdapter {


        public MyAdapter(FragmentManager fm) {
            super(fm);              
        }

        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        @Override
        public Fragment getItem(int position) {
            return InventoryDetailFragment.newInstance(position);
        }
    }

2.)我有一种方法试图找出需要下载的图像的大小而不将其放入内存中。然后在下载到所需大小的同时压缩图像。这没有成功实施。但我不确定出了什么问题。

private Bitmap downloadBitmap(String url, int width, int height) {
    Bitmap bitmap = null;
    int scale = 1;
    try {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;  
        bitmap = BitmapFactory.decodeStream((InputStream)new URL (url).getContent(), null, options);

        if (options.outHeight > height || options.outWidth > width) {
            scale = (int) Math.max(((options.outHeight)/ height), ((options.outWidth)/ width));             }

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        bitmap = BitmapFactory.decodeStream((InputStream)new URL (url).getContent(), null, o2); 
        cache.put(url, new SoftReference<Bitmap>(bitmap));


    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Error e){
        Log.d("TEST", "Garbage Collector called!");
        System.gc();
    }
    return bitmap;
}

我已经尝试了所有我知道如何做的事情,但这超出了我对 Android/Java 的微薄掌握。请帮忙!谢谢!

4

2 回答 2

1

您需要更改以下几点:

  1. 这是一个可怕的想法:BitmapFactory.decodeStream((InputStream)new URL (url).getContent(), null, options);每次执行此操作时,您都会从网络获取图像(因此在您发布的代码中两次)。相反,您需要下载图像并将其缓存在本地。

  2. 将逻辑添加到您的片段中,以便recycle()在片段分离后立即调用位图。添加逻辑以在附加片段时始终重新加载图像(从缓存中)。

  3. 最后,你的inSampleSize计算是错误的。inSampleSize应该是一个 2 的幂的值,例如 1,2,4,8。您可以使用对数或简单的二进制逻辑来获得正确的逻辑,这就是我使用的,它总是使用至少 2 进行下采样(只有在您知道图像太大时才调用它):

-

int ratio =  (int) Math.max((height/options.outHeight), ( width/options.outWidth); //notice that they're flipped     
  for (int powerOfTwo = 64; powerOfTwo >=2; powerOfTwo = powerOfTwo >> 1 ) { //find the biggest power of two that represents the ratio
    if ((ratio & powerOfTwo) > 0) {
      return powerOfTwo;
    }
  }
于 2012-04-04T14:20:54.893 回答
0

如果您使用 opengl 实现您的图形,这将不计入内存。另一种选择是使用

android:largeHeap="true"

在清单中。可能正在工作。

您是否使用 ddvm 来搜索内存泄漏?

http://www.youtube.com/watch?v=_CruQY55HOk

于 2012-04-04T14:16:55.913 回答