我从人们制作的一些主要缓存/图像加载方法中摘录了一部分,并提出了一些使用浏览器缓存并非常快速地加载图像的方法。

我的问题是,有时图像不正确(与另一个图像重复),当我向下滚动imageViews列表时,图像闪烁并随着滚动而变化。 这是我必须忍受的吗?

是的,我为每个imageView创建一个新线程。 我在队列中尝试了一个线程,因此加载时间太长。 即使它们都是单独的线程,也不应使用错误的drawable加载imageView。

这是我的代码。

public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {

    if (imageView != null && urlString != null && urlString.length() > 0)
    {

        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message message) {
                imageView.setImageDrawable((Drawable) message.obj);
            }
        };

        Thread thread = new Thread() {
            @Override
            public void run() {
                if (imageView != null && urlString != null && !urlString.equals(""))
                {
                    URL url;
                    try {
                        InputStream is = fetch(urlString);

                        if (is != null) {
                            Drawable drawable = Drawable.createFromStream((InputStream)is, "src");
                            Message message = handler.obtainMessage(1, drawable);
                            handler.sendMessage(message);
                        } 
                    }
                    catch (MalformedURLException e) {
                        Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
                    } catch (IOException e) {
                        Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
                    }
                }

            }
        };
        thread.start();
    }

}

private InputStream fetch(String urlString) throws MalformedURLException, IOException {
    if (urlString != null)
    {
        URL url = new URL(urlString);

        URLConnection connection = url.openConnection();
        connection.setUseCaches(true);
        Object response = connection.getContent();
        if (response instanceof InputStream) {
            return (InputStream) response;
        }
    }
    return null;
}

* 编辑 ***

毕竟所有评论都是我的代码:我目前正在获取05-19 00:16:49.535:ERROR / AndroidRuntime(12213):java.lang.RuntimeException:画布:尝试使用回收的位图android.graphics.Bitmap @ 4070dab0尝试回收时。

另外,当我没有进行回收时,除了看到图像仍然闪烁外,其他所有操作都有效。 甚至有时会显示错误的图像。

public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {

    if (imageView != null && urlString != null && urlString.length() > 0)
    {
        imageView.setTag(urlString);

        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message message) {
                Drawable d = imageView.getDrawable();
                if(d != null){
                     ((BitmapDrawable)imageView.getDrawable()).getBitmap().recycle();
                     imageView.setImageBitmap(null);
                }

                imageView.setImageDrawable((Drawable) message.obj);
            }
        };

        Thread thread = new Thread() {
            @Override
            public void run() {
                if (imageView != null && urlString != null && !urlString.equals(""))
                {
                    URL url;
                    try {
                        if (imageView.getTag().equals(urlString))
                        {
                            InputStream is = fetch(urlString);

                            if (is != null) {
                                Drawable drawable = Drawable.createFromStream((InputStream)is, "src");
                                Message message = handler.obtainMessage(1, drawable);
                                handler.sendMessage(message);
                            } 
                        }
                    }
                    catch (MalformedURLException e) {
                        Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
                    } catch (IOException e) {
                        Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
                    }
                }

            }
        };
        thread.start();
    }

}

private InputStream fetch(String urlString) throws MalformedURLException, IOException {
    if (urlString != null)
    {
        URL url = new URL(urlString);

        URLConnection connection = url.openConnection();
        connection.setUseCaches(true);
        Object response = connection.getContent();
        if (response instanceof InputStream) {
            return (InputStream) response;
        }
    }
    return null;
}

#1楼 票数:3 已采纳

如果您使用的是ListView ,则应该意识到ListView重用了ImageView实例。 如果加载时间太长,并且与之绑定的特定ImageView已重新用于另一个Image,则您的实现将用旧图像覆盖正确的图像。 你需要:

  1. 修改fetchDrawableOnThread方法以将ImageView标记为要获取的URL:通常,您将使用setTag并保存url。
  2. 提取InputStream后,请检查run方法,以确保ImageView中的getTag值与您刚获取的url匹配。 如果它们不匹配,则ListView将重用此ImageView实例,并且您不应该发送Message来显示图像。

在设置新的Drawable之前,您可能还应该在某个地方调用recycle来清理消耗的位图内存,但这是一个更长的故事。

编辑: recycle故事实际上比我记得的要简单(我查了一些旧代码)。 基本上,在更新ImageViewDrawable之前,请检查它是否已经有一个Drawable集,以及是否确实对其调用了recycle 所以像这样:

ImageView iv = getImageView(); // fetch the image view somehow before you set it;
Drawable d = iv.getDrawable();
if(d != null){
     ((BitmapDrawable)iv.getDrawable()).getBitmap().recycle();
     iv.setImageBitmap(null);
}

这将回收以前的Drawable使用的内存,并且应该有助于解决内存耗尽问题。

#2楼 票数:1

基于Web视图的异步加载和缓存功能的快速简便的解决方案:

String htmlSnippet = "<html><head/><body>" +
                     "<img height=\"50px\" width=\"50px\" src=\"" + item.getImageUrl() + "\" />" +
                     "</body></html>";
imageWebview.loadData( htmlSnippet, "text/html", "utf-8" );

  ask by kgibbon translate from so

未解决问题?本站智能推荐:

1回复

如何在列表视图中缓存imageview?

我遇到与这个人Listview显示错误图像相同的问题 我看到了必须缓存它的解决方案。 但是在我的缓存中,我不确定如何应用解决方案中给出的缓存。 我一直收到错误消息。 我怀疑这是我有问题的部分: 以下是代码。 Adapter.java公共类Adapter扩展BaseAdapter
4回复

将图像从URL加载到imageView以及Cache

嗨,我是android的新手。 我想从URL中插入imageView中的图像,但每当有一次从imageView中的URL加载它时,第二次它应该插入没有互联网意味着它也将存储在缓存中。
1回复

Android-UIL如何仅在未缓存图像时显示加载图像?

我正在使用通用图像库在Android中显示图像。 我知道在DisplayImageOptions中使用showImageOnLoading(img_id)可以使ImageView在加载图像资源时显示正在加载的图像。 当我使用此选项从互联网上抓取图像时,它的效果很好。 但是,从缓存加载图
2回复

如何在Android的另一个ImageView中存储一个ImageView的引用?

我正在从url下载图像并存储在android设备中,我正在尝试将图像从我的android设备显示到ImageView(所有ImageView具有不同的ID)。 我的问题是: 我正在下载图像并尝试在ImageView中显示,但是如果我想在一个以上ImageView中显示同一图像,那么如何在
2回复

Android和多线程中的动画

在尝试向ImageViews中添加动画时,我似乎没有正确的多线程处理,这给了我错误的结果。 这是我叫动画的部分>> 这里的问题是,当我不创建单独的线程时,对于startAnimation()函数,所有3个调用同时发生,并且一切都弄糟了。 但是现在仍然不能完美运行,第一个和第
3回复

Android图像缓存?

您好,我正在开发一个android程序。 我不知道如何缓存图像。 我的图片是从网页加载的。 我在Google上搜索过此内容,但找不到与缓存系统相似的内容。 我的系统正在这样工作; c是显示的图像,x是缓存的图像 xxxxcxxx 有人可以帮助我吗? 谢谢
2回复

防止AndroidVolley缓存图像

我有Volley网络ImageView,问题是在服务器内部更改图像时volley仍使用旧的缓存图像,反正volley是否了解服务器内部图像已更改? 或者如果没有,我如何防止它缓存? 这是我当前的代码:
1回复

SmartImageVIew,我想强制刷新(而不是缓存)

我正在使用这个有用的类,该类允许智能在线下载图像(从loopj伙计们)。 它工作正常,但如果在服务器中可能已更改了相同名称的图像,则我不能强行“刷新”(例如:我更新了我的个人资料图片)。 因此,目前我正在强制残酷删除setImageUrl()之前的应用程序缓存目录。 它可以工作,并且会引发