public class ImageLoaders { String str = new String(); MemoryCache memoryCache = new MemoryCache(); FileCache fileCache; public static Bitmap bitmap; private Map<ImageView, String> imageViews = Collections .synchronizedMap(new HashMap<ImageView, String>()); ArrayList<String> urllist = new ArrayList<String>(); public ImageLoaders(Context context) { photoLoaderThread.setPriority(Thread.NORM_PRIORITY - 1); fileCache = new FileCache(context); } final int stub_id = R.drawable.icon; public void DisplayImage(String url, Activity activity, ImageView imageView) { imageViews.put(imageView, url); urllist.add(url); if (urllist.size() > 1) { Iterator it = urllist.iterator(); int i = 0; while (it.hasNext()) { String ss = (String) it.next(); if (i < urllist.size() - 1) { if (memoryCache.get(ss) != null && !memoryCache.get(ss).isRecycled()) { Bitmap bit = memoryCache.get(ss); bit = null; } } i++; } urllist.clear(); } bitmap = memoryCache.get(url); if (bitmap != null) { imageView.setImageBitmap(bitmap); } else { queuePhoto(url, activity, imageView); imageView.setImageResource(stub_id); } } private void queuePhoto(String url, Activity activity, ImageView imageView) { photosQueue.Clean(imageView); PhotoToLoad p = new PhotoToLoad(url, imageView); synchronized (photosQueue.photosToLoad) { photosQueue.photosToLoad.push(p); photosQueue.photosToLoad.notifyAll(); } // start thread if it's not started yet if (photoLoaderThread.getState() == Thread.State.NEW) photoLoaderThread.start(); } private Bitmap getBitmap(String url) { File f = fileCache.getFile(url); // from SD cache Bitmap b = decodeFile(f); if (b != null) return b; // from web try { Bitmap bitmap = null; URL imageUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) imageUrl .openConnection(); conn.setConnectTimeout(30000); conn.setReadTimeout(30000); InputStream is = conn.getInputStream(); OutputStream os = new FileOutputStream(f); com.monsou.photography.publicmethod.Utils.CopyStream(is, os); os.close(); bitmap = decodeFile(f); return bitmap; } catch (Exception ex) { ex.printStackTrace(); return null; } } // decodes image and scales it to reduce memory consumption private Bitmap decodeFile(File f) { try { // decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(new FileInputStream(f), null, o); // Find the correct scale value. It should be the power of 2. final int REQUIRED_SIZE = 240; int width_tmp = o.outWidth, height_tmp = o.outHeight; int scale = 1; while (true) { if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) break; width_tmp /= 2; height_tmp /= 2; scale *= 2; } // decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); } catch (FileNotFoundException e) { } return null; } // Task for the queue private class PhotoToLoad { public String url; public ImageView imageView; public PhotoToLoad(String u, ImageView i) { url = u; imageView = i; } } PhotosQueue photosQueue = new PhotosQueue(); public void stopThread() { photoLoaderThread.interrupt(); } // stores list of photos to download class PhotosQueue { private Stack<PhotoToLoad> photosToLoad = new Stack<PhotoToLoad>(); // removes all instances of this ImageView public void Clean(ImageView image) { for (int j = 0; j < photosToLoad.size();) { if (photosToLoad.get(j).imageView == image) photosToLoad.remove(j); else ++j; } } } class PhotosLoader extends Thread { public void run() { try { while (true) { // thread waits until there are any images to load in the // queue if (photosQueue.photosToLoad.size() == 0) synchronized (photosQueue.photosToLoad) { photosQueue.photosToLoad.wait(); } if (photosQueue.photosToLoad.size() != 0) { PhotoToLoad photoToLoad; synchronized (photosQueue.photosToLoad) { photoToLoad = photosQueue.photosToLoad.pop(); } Bitmap bmp = getBitmap(photoToLoad.url); memoryCache.put(photoToLoad.url, bmp); String tag = imageViews.get(photoToLoad.imageView); if (tag != null && tag.equals(photoToLoad.url)) { BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad.imageView); Activity a = (Activity) photoToLoad.imageView .getContext(); a.runOnUiThread(bd); } } if (Thread.interrupted()) break; } } catch (InterruptedException e) { // allow thread to exit } } } PhotosLoader photoLoaderThread = new PhotosLoader(); // Used to display bitmap in the UI thread class BitmapDisplayer implements Runnable { Bitmap bitmap; ImageView imageView; public BitmapDisplayer(Bitmap b, ImageView i) { bitmap = b; imageView = i; } public void run() { if (bitmap != null) { imageView.setImageBitmap(bitmap); } else { imageView.setImageResource(stub_id); } } } public void clearCache() { memoryCache.clear(); fileCache.clear(); } }
在适配器中调用
class GalleryAdapter extends BaseAdapter { Context c; private ImageLoaders imageLoader; public GalleryAdapter(Context c) { imageLoader = new ImageLoaders(c); this.c = c; } @Override public int getCount() { return productList.getAllItems().size(); } @Override public Object getItem(int position) { return productList.getAllItems().get(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 = LayoutInflater.from(c).inflate( R.layout.product_tiem_01, parent, false); holder.imagerView = (ImageView) convertView .findViewById(R.id.imageView1); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } String str_iv = productList.getItem(position).getSmallimg(); imageLoader.DisplayImage(str_iv, ProductActivity.this, holder.imagerView); return convertView; } } public static class ViewHolder { ImageView imagerView; }