接着这篇博客写:http://blog.csdn.net/two_water/article/details/51477206
异步加载1这篇博客在最后暴露出了一个问题,就是只在ListView的最后一个Item的ImageView刷新图片,解决问题的方案也提出来了,需要让url和对应的ImageView进行下配对!
ImageLoader的代码把showImageByThread方法里面的判断是否有缓存图片的代码注释了,改到在Adapter那里进行判断,判断是否有缓存图片,如果有显示缓存的图片,如果没有就先显示默认加载的图片,然后再去加载网络图片,并添加缓存!
package com.liangdianshui.asynchronouslyload;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
/**
* Created by 两点水 on 2016/5/12.
*/
public class MyAdapter extends BaseAdapter {
private Context context;
private List<DataBean> list;
private ViewHolder mHolder;
private ImageLoader mImaeLoader;
public MyAdapter(Context context, List<DataBean> list) {
this.context = context;
this.list = list;
mImaeLoader = new ImageLoader(); //因为创建了缓存空间,所以放在构造方法,只创建一次
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.item_layout, null);
mHolder = new ViewHolder();
mHolder.tvTitle = (TextView) convertView.findViewById(R.id.tv_title);
mHolder.tvContent = (TextView) convertView.findViewById(R.id.tv_content);
mHolder.ivIcon = (ImageView) convertView.findViewById(R.id.iv_icon);
convertView.setTag(mHolder);
} else {
mHolder = (ViewHolder) convertView.getTag();
}
// mHolder.ivIcon.setImageResource(R.mipmap.ic_launcher);//默认加载的图片
String url = list.get(position).getDataIconUrl();
mHolder.ivIcon.setTag(url);//为防止listview显示的图片错乱,重复,闪烁
// new ImageLoader().showImageByThread(mHolder.ivIcon, url);
Bitmap bitmapFromCache = mImaeLoader.getBitmapFromCache(url);
if (bitmapFromCache != null) {
mHolder.ivIcon.setImageBitmap(bitmapFromCache);
}else{
mHolder.ivIcon.setImageResource(R.mipmap.ic_launcher);
mImaeLoader.showImageByThread(mHolder.ivIcon, url);
}
mHolder.tvTitle.setText(list.get(position).getDataTitle());
mHolder.tvContent.setText(list.get(position).getDataContent());
return convertView;
}
class ViewHolder {
private TextView tvTitle;
private TextView tvContent;
private ImageView ivIcon;
}
}
ImageLoader的代码:
package com.liangdianshui.asynchronouslyload;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.util.LruCache;
import android.widget.ImageView;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Created by 两点水 on 2016/5/22.
*/
public class ImageLoader {
private ImageView mImageView;
private String mUrl;
private final int URL_BITMAP = 0;
private LruCache<String, Bitmap> mCache; //使用Lru缓存(使用的Lru算法:近期最少使用算法)
/**
* 使用缓存肯定要先声明缓存空间,因此在构造方法中声明缓存空间
*/
public ImageLoader() {
//获取程序最大使用的内存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheSize = maxMemory / 4; //缓存大小为最大缓存的四分之一
//创建缓存,把缓存大小传进去
mCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
//每次存入缓存的时候都会调用这个方法,因此我们把图片的大小放进去
return value.getByteCount();
}
};
}
/**
* 把图片加入到缓存
*
* @param url
* @param bitmap
*/
public void addBitmapToCache(String url, Bitmap bitmap) {
//LruCache好比是一个map,采用键值对的形式去保存图片
if (getBitmapFromCache(url) == null) {
//如果缓存中没有这个Bitmap,就把bitmap放进缓存
mCache.put(url, bitmap);
}
}
/**
* 从缓存中获取图片
*
* @param url
*/
public Bitmap getBitmapFromCache(String url) {
return mCache.get(url); //根据url获取图片
}
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case URL_BITMAP:
// if (mImageView.getTag().equals(mUrl)) {
// mImageView.setImageBitmap((Bitmap) msg.obj);
// }
//因为传过来的对象更改了,这里也要跟着更改
ImgHolder holder = (ImgHolder) msg.obj;
if (holder.imageView.getTag().equals(holder.url)) {
holder.imageView.setImageBitmap(holder.bitmap);
}
break;
}
}
};
/**
* 多线程加载图片(Thread+Handler)
* 根据url获取的itmap显示在ImageView中
*
* @param imageView
* @param url
*/
public void showImageByThread(final ImageView imageView, final String url) {
mImageView = imageView;
mUrl = url;
//从缓存中取出图片
// Bitmap bitmap = getBitmapFromCache(url);
//判断缓存中是否含有这张图片,没有的话去网络下载图片
// if (bitmap == null) {
new Thread(new Runnable() {
@Override
public void run() {
Bitmap bitmap = getBitmapFromURL(url);
//把下载下来的图片加到缓存中
if (bitmap != null) {
addBitmapToCache(url, bitmap);
}
Message message = new Message();
// message.obj = bitmap;