package com.openims.utility; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.Thread.State; import java.lang.ref.SoftReference; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.HashMap; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Bitmap.CompressFormat; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Handler; import android.util.Log; public class ImageThreadLoader { private String diskurl; private CompressFormat compressedImageFormat = CompressFormat.PNG; private int cachedImageQuality = 75; private Context context; private final HashMap<String, SoftReference<Bitmap>> Cache = new HashMap<String, SoftReference<Bitmap>>(); private final class QueueItem { public URL url; public ImageLoadedListener listener; } private final ArrayList<QueueItem> Queue = new ArrayList<QueueItem>(); private final Handler handler = new Handler(); // Assumes that this is started from the main (UI) thread private Thread thread; private QueueRunner runner = new QueueRunner();; /** Creates a new instance of the ImageThreadLoader */ public ImageThreadLoader(Context context) { this.context = context; this.diskurl = context.getApplicationContext().getCacheDir() + "/upcache/imagecache"; new File(diskurl).mkdirs(); thread = new Thread(runner); } private File getImageFile(String imageUrl) { String fileName = Integer.toHexString(imageUrl.hashCode()) + "." + compressedImageFormat.name(); return new File(this.diskurl + "/" + fileName); } private String getFullPath(String imageUrl){ return this.diskurl + "/" + Integer.toHexString(imageUrl.hashCode()) + "." + compressedImageFormat.name(); } public interface ImageLoadedListener { public void imageLoaded(Bitmap imageBitmap ); } private class QueueRunner implements Runnable { public void run() { synchronized(this) { while(Queue.size() > 0) { final QueueItem item = Queue.remove(0); // If in the cache, return that copy and be done if( Cache.containsKey(item.url.toString()) && Cache.get(item.url.toString()) != null) { // Use a handler to get back onto the UI thread for the update handler.post(new Runnable() { public void run() { if( item.listener != null ) { // NB: There's a potential race condition here where the cache item could get // garbage collected between when we post the runnable and it's executed. // Ideally we would re-run the network load or something. SoftReference<Bitmap> ref = Cache.get(item.url.toString()); if( ref != null ) { item.listener.imageLoaded(ref.get()); } } } }); } else { final Bitmap bmp = readBitmapFromNetwork(item.url); if( bmp != null ) { Cache.put(item.url.toString(), new SoftReference<Bitmap>(bmp)); try{ File imageFile = getImageFile(item.url.toString()); imageFile.createNewFile(); FileOutputStream ostream = new FileOutputStream(imageFile); bmp.compress(compressedImageFormat, cachedImageQuality, ostream); ostream.close(); }catch(Throwable e){ } // Use a handler to get back onto the UI thread for the update handler.post(new Runnable() { public void run() { if( item.listener != null ) { item.listener.imageLoaded(bmp); } } }); } } } } } } public Bitmap loadImage( final String uri, final ImageLoadedListener listener) throws MalformedURLException { // If it's in the cache, just get it and quit it Log.e("*********", "--1"); if( Cache.containsKey(uri)) { SoftReference<Bitmap> ref = Cache.get(uri); if( ref != null ) { return ref.get(); } } Log.e("*********", "--2"); File imageFile = getImageFile(uri); if (imageFile.exists()) { String path = getFullPath(uri); Drawable draw = Drawable.createFromPath(path); Bitmap bit = ((BitmapDrawable)draw).getBitmap(); return bit; } Log.e("*********", "--3"); QueueItem item = new QueueItem(); item.url = new URL(uri); item.listener = listener; Queue.add(item); // start the thread if needed if( thread.getState() == State.NEW) { thread.start(); } else if( thread.getState() == State.TERMINATED) { thread = new Thread(runner); thread.start(); } return null; } public static Bitmap readBitmapFromNetwork( URL url ) { InputStream is = null; BufferedInputStream bis = null; Bitmap bmp = null; Log.e("*********", "--4"); try { URLConnection conn = url.openConnection(); conn.connect(); is = conn.getInputStream(); bis = new BufferedInputStream(is); bmp = BitmapFactory.decodeStream(bis); } catch (MalformedURLException e) { Log.e("*************", "Bad ad URL", e); } catch (IOException e) { Log.e("******************", "Could not get remote ad image", e); } finally { try { if( is != null ) is.close(); if( bis != null ) bis.close(); } catch (IOException e) { Log.w("*************", "Error closing stream."); } } Log.e("*********", "--5"); return bmp; } }