为了账号安全,请及时绑定邮箱和手机立即绑定

LruCash使用showImageByThread有Bug

1.剛載入時,可見項目除了最後一個有載入圖片(有時還錯位),其它只顯示ic_launcher

http://img1.sycdn.imooc.com//557704bd0001efde07681280.jpg

2.要滾動畫面好幾次才會全部載入對應的圖片

程式碼如下 

ImageLoader.java

ImageView imageView;
String url;
LruCache<String, Bitmap> bitmapLruCache;

public ImageLoader() {
    int maxMemory = (int) Runtime.getRuntime().maxMemory();
    int cashSize = maxMemory / 4;
    bitmapLruCache = new LruCache<String, Bitmap>(cashSize) {
        @Override
        protected int sizeOf(String key, Bitmap value) {
            return value.getByteCount();
        }
    };
}

private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if (imageView.getTag().equals(url)) {
            imageView.setImageBitmap((Bitmap) msg.obj);
        }
    }
};

public void showImageByThread(ImageView imageView, final String url) {

    this.imageView = imageView;
    this.url = url;
    Bitmap bitmap = getBitmapFromCash(url);

    //緩衝沒有bitmap,從網路下載

    if (bitmap == null) {
        new Thread() {
            @Override
            public void run() {
                Bitmap bitmap = getBitmapFromURL(url);
                //將下載的bitmap存到緩衝
                addBitmapToCash(url, bitmap);

                Message msg = Message.obtain();
                msg.obj = bitmap;
                handler.sendMessage(msg);
            }
        }.start();
    } else {
        imageView.setImageBitmap(bitmap);
    }
}

public Bitmap getBitmapFromURL(String url) {
    Bitmap bitmap = null;
    try {
        URLConnection connection = new URL(url).openConnection();
        InputStream is = connection.getInputStream();
        bitmap = BitmapFactory.decodeStream(is);
        is.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return bitmap;
}

public void addBitmapToCash(String url, Bitmap bitmap) {
    if (bitmap != null) {
        bitmapLruCache.put(url, bitmap);
    }
}

public Bitmap getBitmapFromCash(String url) {
    return bitmapLruCache.get(url);
}


正在回答

4 回答

还有个可能,看你代码你加载图片的时候是不是调用的showImageByThread(ImageView imageView, final String url)

这个方法?

你这个loader中只有1个ImageView的引用,多次调用后,这个引用只指向最后一个ImageView,这也许就是为什么只有最后一个图片显示的原因吧。

显示网络图片有好多库可以用,universalImageLoader,google的volley。。。。。

1 回复 有任何疑惑可以回复我~
#1

eric_0023 提问者

有可能,但為了多次滑動後就每個對應圖片就能顯示
2015-06-10 回复 有任何疑惑可以回复我~
#2

orangesweet 回复 eric_0023 提问者

多次滑动相当于多次调用吧,再次调用的时候图片应该已经下好了,直接从缓存中取,比较快,有可能在下次调用showImageByThread前,就已经把上一个imageview的图片从缓存中取出,并且显示好了。
2015-06-10 回复 有任何疑惑可以回复我~
#3

eric_0023 提问者 回复 orangesweet

很有道理,謝謝,我試著改看看
2015-06-10 回复 有任何疑惑可以回复我~
#4

eric_0023 提问者

非常感谢!
2015-06-10 回复 有任何疑惑可以回复我~
查看1条回复

把new handler的操作放在你的showImageByThread()里就可以了

1 回复 有任何疑惑可以回复我~

回复 iceliuorange:可以了,把圖片下載獨立成內部類,呼叫時把imageview和url傳進去

public void showImageByThread(ImageView imageView, final String url) {
    Bitmap bitmap = getBitmapFromCash(url);

    //緩衝沒有bitmap,從網路下載
    if (bitmap == null) {
        new ImageHandlerThreat(imageView, url).startThread();
    } else {
        imageView.setImageBitmap(bitmap);
    }
}

private class ImageHandlerThreat {
    private ImageView imageView;
    private String url;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (imageView.getTag().equals(url)) {
                imageView.setImageBitmap((Bitmap) msg.obj);
            }
        }
    };

    public ImageHandlerThreat(ImageView imageView, String url) {
        this.imageView = imageView;
        this.url = url;
    }

    public void startThread() {
        new Thread() {
            @Override
            public void run() {
                Bitmap bitmap = getBitmapFromURL(url);
                //將下載的bitmap存到緩衝
                addBitmapToCash(url, bitmap);

                Message msg = Message.obtain();
                msg.obj = bitmap;
                handler.sendMessage(msg);
            }
        }.start();
    }
}


1 回复 有任何疑惑可以回复我~

public void handleMessage(Message msg) {

        if (imageView.getTag().equals(url)) {

            imageView.setImageBitmap((Bitmap) msg.obj);

        }

    }

这里打个断点,看是什么问题

0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
Android必学-异步加载
  • 参与学习       50627    人
  • 解答问题       311    个

了解Android中的异步加载处理方法,这是面试问的最多的知识点

进入课程

LruCash使用showImageByThread有Bug

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信