【问题标题】:Out-of-memory errors using ImageGetter to grab images from HTML使用 ImageGetter 从 HTML 中抓取图像的内存不足错误
【发布时间】:2015-04-24 17:31:02
【问题描述】:

我正在编写一个应用程序来显示来自网站的帖子并使用Html.fromHtml 来执行此操作。但是,如果我打开一篇文章,它会立即使用大约 25MB 的内存来加载图像。即使图像存储在设备上,这也是可以接受的,只有重新加载同一篇文章会导致另一个 25MB 的跳转。我环顾四周并尝试了大量建议的解决方案。我觉得我需要回收位图,只是我不确定在哪里执行此操作。代码如下:

public class ImageGetter implements Html.ImageGetter {
private Context c;
private TextView container;
private ImageLoader imageLoader;
private DisplayImageOptions options;
private UrlImageDownloader urlDrawable;

public ImageGetter(View t, Context c) {
    this.c = c;
    this.container = (TextView)t;

    imageLoader = ImageLoader.getInstance();
    options = new DisplayImageOptions.Builder().cacheOnDisk(true).cacheInMemory(false).imageScaleType(ImageScaleType.EXACTLY)
            .showImageOnLoading(R.color.darkcolorPrimary).bitmapConfig(Bitmap.Config.RGB_565).resetViewBeforeLoading(true).build();
}

@Override
public Drawable getDrawable(String source) {
    urlDrawable = new UrlImageDownloader(c.getResources(), source);
    imageLoader.loadImage(source, options, new SimpleListener(urlDrawable));
    return urlDrawable;
}

private class SimpleListener extends SimpleImageLoadingListener
{
    UrlImageDownloader urlImageDownloader;

    public SimpleListener(UrlImageDownloader downloader) {
        super();
        urlImageDownloader = downloader;
    }

    @Override
    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
        int width = loadedImage.getWidth();
        int height = loadedImage.getHeight();

        int newWidth = width;
        int newHeight = height;

        if( width > container.getWidth() ) {
            newWidth = container.getWidth();
            newHeight = (newWidth * height) / width;
        }

        Drawable result = new BitmapDrawable(c.getResources(), loadedImage);
        result.setBounds(0, 0, newWidth, newHeight);

        urlImageDownloader.setBounds(0, 0, newWidth, newHeight);
        urlImageDownloader.drawable = result;

        container.setText(container.getText());
    }
}

public class UrlImageDownloader extends BitmapDrawable
{
    public Drawable drawable;

    /**
     * Create a drawable by decoding a bitmap from the given input stream.
     *
     * @param res
     * @param is
     */
    public UrlImageDownloader(Resources res, InputStream is) {
        super(res, is);
    }

    /**
     * Create a drawable by opening a given file path and decoding the bitmap.
     *
     * @param res
     * @param filepath
     */
    public UrlImageDownloader(Resources res, String filepath) {
        super(res, filepath);
        drawable = new BitmapDrawable(res, filepath);
    }

    /**
     * Create drawable from a bitmap, setting initial target density based on
     * the display metrics of the resources.
     *
     * @param res
     * @param bitmap
     */
    public UrlImageDownloader(Resources res, Bitmap bitmap) {
        super(res, bitmap);
    }

    @Override
    public void draw(Canvas canvas) {
        // override the draw to facilitate refresh function later
        if(drawable != null) {
            drawable.draw(canvas);
        }
    }
}

}

【问题讨论】:

    标签: java android memory bitmap universal-image-loader


    【解决方案1】:

    解决了。存在涉及存储图像的TextView 的内存泄漏。如果您遇到此类问题,我建议您使用 Eclipse MAT 来识别内存泄漏。

    【讨论】:

      【解决方案2】:

      您可以通过调用recycle 方法删除位图。 但这本身不会有太大的作用,你应该通过调用System.gc()来调用垃圾收集器,他会将其从内存中清除。

      【讨论】:

      • 是的,我已经尝试调用垃圾收集器,但影响很小,我觉得对位图的引用被保存在我无法弄清楚的地方。
      • 这是你应该尝试的:在 android studio 中打开内存监视器并加载位图,加载另一个位图并在内存监视器中启动 GC。如果内存使用量没有减少,那么您就有泄漏。如果是这样,你在错误的地方调用垃圾收集器
      • 是的,它没有减少。我有泄漏,我只是不知道它在哪里。
      猜你喜欢
      • 1970-01-01
      • 2011-12-05
      • 2013-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      • 1970-01-01
      相关资源
      最近更新 更多