package mobi.urika.android.widget; import java.io.IOException; import java.io.InputStream; import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.HashMap; import java.util.Map.Entry; import android.content.ContentResolver; import android.content.Context; import android.graphics.drawable.Drawable; import android.net.Uri; import android.util.Log; public class ListViewImageManager { private static final String TAG = "ListViewImageManager"; private static final boolean LOGD = false; private static ListViewImageManager instance; public static ListViewImageManager getInstance() { if (instance == null) instance = new ListViewImageManager(); return instance; } private final HashMap<String, SoftReference<Drawable>> mCacheForImageByUri = new HashMap<String, SoftReference<Drawable>>(); private final HashMap<Integer, ArrayList<String>> mWidgetCacheUsageByUri = new HashMap<Integer, ArrayList<String>>(); private final HashMap<Integer, SoftReference<Drawable>> mCacheForImageById = new HashMap<Integer, SoftReference<Drawable>>(); private final HashMap<Integer, ArrayList<Integer>> mWidgetCacheUsageById = new HashMap<Integer, ArrayList<Integer>>(); public Drawable getImageFromUri(Context mContext, int widgetId, String imgUri) { Drawable d = null; if (mCacheForImageByUri.containsKey(imgUri) && mCacheForImageByUri.get(imgUri) != null) { SoftReference<Drawable> ref = mCacheForImageByUri.get(imgUri); if (ref != null) { d = ref.get(); } } if (LOGD) if (d != null) Log.d(TAG, "image URI restored (width = " + d.getMinimumWidth() + " / weight = " + d.getMinimumHeight() + ")"); if (d == null) { Uri mUri = Uri.parse(imgUri); String scheme = mUri.getScheme(); if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) { // try { // // Load drawable through Resources, to get the source density // information // ContentResolver.OpenResourceIdResult r = // mContext.getContentResolver().getResourceId(mUri); // d = r.r.getDrawable(r.id); // } catch (Exception e) { // Log.w("ImageView", "Unable to open content: " + mUri, e); // } Log.w("ImageView", "Unable to open content: " + mUri); } else if (ContentResolver.SCHEME_CONTENT.equals(scheme) || ContentResolver.SCHEME_FILE.equals(scheme)) { try { d = Drawable.createFromStream(mContext.getContentResolver().openInputStream(mUri), null); } catch (Exception e) { Log.w("ImageView", "Unable to open content: " + mUri, e); } } else { d = Drawable.createFromPath(mUri.toString()); } if (LOGD) Log.d(TAG, "image URI decoded (width = " + d.getMinimumWidth() + " / weight = " + d.getMinimumHeight() + ")"); mCacheForImageByUri.put(imgUri, new SoftReference<Drawable>(d)); // store image key usage ArrayList<String> list = mWidgetCacheUsageByUri.get(widgetId); if (list == null) list = new ArrayList<String>(); list.add(imgUri); mWidgetCacheUsageByUri.put(widgetId, list); } return d; } public Drawable getImageFromId(Context ctx, int widgetId, int imgId) { Drawable drawable = null; if (mCacheForImageById.containsKey(imgId) && mCacheForImageById.get(imgId) != null) { SoftReference<Drawable> ref = mCacheForImageById.get(imgId); if (ref != null) { drawable = ref.get(); } else { if (LOGD) Log.d(TAG, "image ID missing !!!!!!!!!!"); } } if (LOGD) if (drawable != null) Log.d(TAG, "image ID restored"); if (drawable == null) { if (LOGD) Log.d(TAG, "image ID decoded"); InputStream rawResource = ctx.getResources().openRawResource( imgId); try { drawable = Drawable.createFromStream(rawResource, ctx.getResources().getResourceName(imgId)); } finally { try { rawResource.close(); } catch (IOException e) { e.printStackTrace(); } } mCacheForImageById.put(imgId, new SoftReference<Drawable>(drawable)); // store image key usage ArrayList<Integer> list = mWidgetCacheUsageById.get(widgetId); if (list == null) list = new ArrayList<Integer>(); list.add(imgId); mWidgetCacheUsageById.put(widgetId, list); } return drawable; } public void unbindDrawables() { for (Entry<Integer, SoftReference<Drawable>> drawableEntry : mCacheForImageById.entrySet()) { if ((drawableEntry != null) && (drawableEntry.getValue() != null) && (drawableEntry.getValue().get() != null)) drawableEntry.getValue().get().setCallback(null); } for (Entry<String, SoftReference<Drawable>> drawableEntry : mCacheForImageByUri.entrySet()) { if ((drawableEntry != null) && (drawableEntry.getValue() != null) && (drawableEntry.getValue().get() != null)) drawableEntry.getValue().get().setCallback(null); } } public void clearCache() { mCacheForImageById.clear(); mCacheForImageByUri.clear(); } public String clearCacheForWidget(Context ctx, int widgetId) { Drawable drawable = null; ArrayList<String> listByUri = mWidgetCacheUsageByUri.get(widgetId); if (listByUri != null) { for (String imgUri : listByUri) { if (mCacheForImageByUri.containsKey(imgUri) && mCacheForImageByUri.get(imgUri) != null) { SoftReference<Drawable> ref = mCacheForImageByUri.get(imgUri); if (ref != null) { drawable = ref.get(); if (drawable != null) drawable.setCallback(null); } mCacheForImageByUri.remove(imgUri); Log.d(TAG, "image URI removed from cache : " + imgUri); } } } mWidgetCacheUsageByUri.remove(widgetId); ArrayList<Integer> listById = mWidgetCacheUsageById.get(widgetId); if (listById != null) { for (Integer imgId : listById) { if (mCacheForImageById.containsKey(imgId) && mCacheForImageById.get(imgId) != null) { SoftReference<Drawable> ref = mCacheForImageById.get(imgId); if (ref != null) { drawable = ref.get(); if (drawable != null) drawable.setCallback(null); } mCacheForImageById.remove(imgId); Log.d(TAG, "image ID removed from cache : " + imgId); } } } mWidgetCacheUsageById.remove(widgetId); return null; } }