标签:
public class ImageLoader { //一级缓存的最大数量 private static final int MAX_CAPACTITY = 20; //下载图片时的默认图片 private DefaultImage image = new DefaultImage(); private Context mContext; private ImageLoader(Context context){ this.mContext = context; } private ImageLoader(){}; private static ImageLoader instance; public static ImageLoader getInstance(Context context){ if(instance == null){ instance = new ImageLoader(context); } return instance; } //三级缓存 //一级缓存 强引用 在内存溢出时 也不回收 //20张 /** * String bitmap的路径 * bitmap 图片 */ private LinkedHashMap<String, Bitmap> firstCacheIma = new LinkedHashMap<String, Bitmap>(MAX_CAPACTITY, 0.75f, true){ //根据返回值移除map中最老的值 protected boolean removeEldestEntry(java.util.Map.Entry<String,Bitmap> eldest) { if(this.size() > MAX_CAPACTITY){ //加入二级缓存 软引用 在内存不足,回收 secondCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue())); //加入三级缓存 本地缓存 diskCache(eldest.getKey(),eldest.getValue()); } return false; } }; /** * 本地缓存 * @param key 图片的路径 (会被当做名称保存到硬盘) * @param value */ private void diskCache(String key, Bitmap value) { String name = MD5utils.decode(key); String path = mContext.getCacheDir().getAbsolutePath()+ File.separator +name; FileOutputStream fos = null; try { fos = new FileOutputStream(path); //保存成JPG格式 value.compress(Bitmap.CompressFormat.JPEG, 100, fos); } catch (FileNotFoundException e) { e.printStackTrace(); }finally{ if(fos != null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }; //二级缓存,超过20张 //线程安全 并发的 private static ConcurrentHashMap<String, SoftReference<Bitmap>> secondCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>(); //三级缓存;本地缓存 写入内部存储 public void loadImage(String key,ImageView imageView){ //读取缓存 Bitmap bitmap = getFromCachr(key); if(bitmap != null){ cancelDownload(key, imageView); imageView.setImageBitmap(bitmap); }else{ //设置默认图片 imageView.setImageDrawable(image); //访问网络 AsynImagLoaderTask task = new AsynImagLoaderTask(imageView); task.execute(key); } } //异步下载图片 class AsynImagLoaderTask extends AsyncTask<String, Void , Bitmap>{ private String key; private ImageView imageView; public AsynImagLoaderTask(ImageView imageView) { super(); this.imageView = imageView; } @Override protected Bitmap doInBackground(String... params) { key = params[0]; return downLoadImag(key); } @Override protected void onPostExecute(Bitmap result) { super.onPostExecute(result); if(isCancelled()){ result =null; } if(result != null){ //添加到一级缓存 addFirstCache( key, result); //显示图片 imageView.setImageBitmap(result); } } } private void cancelDownload(String key,ImageView result){ //可能有多个任务下载同一张图片 AsynImagLoaderTask task = new AsynImagLoaderTask(result); if( task != null){ String downKey = task.key; if(downKey == null || !downKey.equals(key)){ //设置标识 task.cancel(true); } } } /** * 加入一级缓存 * @param key2 * @param result */ private void addFirstCache(String key2, Bitmap result) { if(result != null){ synchronized (firstCacheIma) { firstCacheIma.put(key2, result); } } } private Bitmap getFromCachr(String key) { //从一级缓存加载 synchronized (firstCacheIma) { Bitmap bitmap = firstCacheIma.get(key); //保持图片的新鲜 if(bitmap != null){ firstCacheIma.remove(bitmap); firstCacheIma.put(key, bitmap); return bitmap; } } //从二级缓存加载 SoftReference<Bitmap> softReference = secondCache.get(key); if(softReference != null){ Bitmap bitmap = softReference.get(); if(bitmap != null){ //添加到一级缓存 firstCacheIma.put(key, bitmap); return bitmap; } }else{ //软引用呗回收了,从缓存中清楚 secondCache.remove(key); } //从本地缓存加载 Bitmap load_bitmap = getFromLocal( key); if(load_bitmap != null){ //添加到一级缓存 firstCacheIma.put(key, load_bitmap); return load_bitmap; } return null; } /** * 从本地缓存中读取 * @param key * @return */ private Bitmap getFromLocal(String key) { String name = MD5utils.decode(key); if(name == null){ return null; } String path = mContext.getCacheDir().getAbsolutePath() + File.separator + name; FileInputStream fis = null; try { fis = new FileInputStream(path); return BitmapFactory.decodeStream(fis); } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } /** * 下载图片 * @param key2 * @return */ private Bitmap downLoadImag(String key2) { InputStream is = null; try { is = DownImag.getImag(key2); return BitmapFactory.decodeStream(is); } catch (IOException e) { e.printStackTrace(); }finally{ if(is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /** * 设置默认图片 * */ static class DefaultImage extends ColorDrawable{ public DefaultImage(){ super(Color.GRAY); } } }
Adapter中使用:
public class MyAdapter extends BaseAdapter{ private Context context; private LayoutInflater inflater; private ImageLoader loader; private String[] str; public MyAdapter (Context context,String[] str){ this.context = context; inflater = LayoutInflater.from(context); this.str= str; loader = ImageLoader.getInstance(context); } @Override public int getCount() { return str.length; } @Override public Object getItem(int position) { return str[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if(convertView == null){ holder = new ViewHolder(); convertView = inflater.inflate(com.example.test.R.layout.list_item, null); holder.imageView = (ImageView) convertView.findViewById(com.example.test.R.id.item); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } loader.loadImage(str[position], holder.imageView); return convertView; } class ViewHolder{ ImageView imageView; } }
Md5Utils
public class MD5utils { public static String decode(String key){ MessageDigest digest = null; try { digest = MessageDigest.getInstance("MD5"); digest.reset(); //UTF-8编码 digest.update(key.getBytes("utf-8")); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } byte[] byteArray = digest.digest(); StringBuffer buffer = new StringBuffer(); for(int i = 0; i< byteArray.length;i++){ } return key; } }
DownImage:
public class DownImag { public static InputStream getImag(String key) throws IOException{ URL url = new URL(key); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); return connection.getInputStream(); } }
标签:
原文地址:http://www.cnblogs.com/wei1228565493/p/4676924.html