项目用到异步加载头像LasyList
package com.leo.proforjob; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Handler; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ImageLoader { private MemoryCache memoryCache = new MemoryCache(); private Map<ImageProcessingCallback, Long> callbacks = Collections.synchronizedMap(new WeakHashMap<ImageProcessingCallback, Long>()); private ExecutorService executorService; private Handler handler = new Handler();// handler to display images in UI thread private ImageLoader() { } private static class SingletonHolder { public static final ImageLoader instance = new ImageLoader(); } public static ImageLoader getInstance() { return SingletonHolder.instance; } public void init(Context context) { executorService = Executors.newFixedThreadPool(5); } public void displayImage(Long id, ImageProcessingCallback imageProcessingCallback) { imageProcessingCallback.onImagePreProcessing(); callbacks.put(imageProcessingCallback, id); Drawable drawable = memoryCache.get(id); if (drawable != null) { imageProcessingCallback.onImageProcessing(drawable); }else { queuePhoto(id, imageProcessingCallback); } } private void queuePhoto(Long id, ImageProcessingCallback imageProcessingCallback) { PhotoToLoad p = new PhotoToLoad(id, imageProcessingCallback); executorService.submit(new PhotosLoader(p)); } // Task for the queue private class PhotoToLoad { public Object id; public ImageProcessingCallback imageProcessingCallback; public PhotoToLoad(Object u, ImageProcessingCallback i) { id = u; imageProcessingCallback = i; } } class PhotosLoader implements Runnable { PhotoToLoad photoToLoad; PhotosLoader(PhotoToLoad photoToLoad) { this.photoToLoad = photoToLoad; } @Override public void run() { try { if (viewReused(photoToLoad)) return; //Drawable drawable = getBitmap(photoToLoad.url); //memoryCache.put(photoToLoad.id, drawable); if (viewReused(photoToLoad)) return; // BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad); //handler.post(bd); } catch (Throwable th) { th.printStackTrace(); } } } boolean viewReused(PhotoToLoad photoToLoad) { Long tag = callbacks.get(photoToLoad.imageProcessingCallback); if (tag == null || !tag.equals(photoToLoad.id)) return true; return false; } // Used to display bitmap in the UI thread class BitmapDisplayer implements Runnable { Drawable bitmap; PhotoToLoad photoToLoad; public BitmapDisplayer(Drawable b, PhotoToLoad p) { bitmap = b; photoToLoad = p; } public void run() { if (viewReused(photoToLoad)) return; if (bitmap != null) { photoToLoad.imageProcessingCallback.onImageProcessing(bitmap); } } } public void clearCache() { memoryCache.clear(); } }
package com.leo.proforjob; import android.graphics.drawable.Drawable; /** * Created by leo on 16/8/1. */ public interface ImageProcessingCallback { void onImagePreProcessing(); void onImageProcessing(Drawable drawable); }
package com.leo.proforjob; import android.graphics.drawable.Drawable; import android.util.Log; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; /** * Created by leo on 16/8/1. */ public class MemoryCache { private static final String TAG = "MemoryCache"; private Map<Object, Drawable> cache= Collections.synchronizedMap( new LinkedHashMap<Object, Drawable>(10,1.5f,true));//Last argument true for LRU ordering private long size=0;//current allocated size private long limit=1000000;//max memory in bytes public MemoryCache(){ //use 25% of available heap size setLimit(Runtime.getRuntime().maxMemory()/4); } public void setLimit(long new_limit){ limit=new_limit; Log.i(TAG, "MemoryCache will use up to "+limit/1024./1024.+"MB"); } public Drawable get(Long id){ try{ if(!cache.containsKey(id)) return null; //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 return cache.get(id); }catch(NullPointerException ex){ ex.printStackTrace(); return null; } } public void put(Object id, Drawable bitmap){ try{ if(cache.containsKey(id)) size-=getSizeInBytes(cache.get(id)); cache.put(id, bitmap); size+=getSizeInBytes(bitmap); checkSize(); }catch(Throwable th){ th.printStackTrace(); } } private void checkSize() { if(size>limit){ Iterator<Map.Entry<Object, Drawable>> iter=cache.entrySet().iterator();//least recently accessed item will be the first one iterated while(iter.hasNext()){ Map.Entry<Object, Drawable> entry=iter.next(); size-=getSizeInBytes(entry.getValue()); iter.remove(); if(size<=limit) break; } } } public void clear() { if (cache !=null) { cache.clear(); } size=0; } long getSizeInBytes(Drawable drawable) { if(drawable==null) return 0; return drawable.getIntrinsicWidth() * drawable.getIntrinsicHeight(); } }
ImageLoader.getInstance().displayImage(id, callback);