利用android開源庫android-gif-drawable加載gif格式圖片
在android項目中,最學用的是png格式的圖片,或者用jpeg的圖片。那我們要用動畫類型圖片gif格式圖片應該怎么辦呢?我們可以使用android-gif-drawable框架來實現gif圖片加載,下面直接貼下我在項目中用到的工具類:
public class GifLoader { /保存圖片引用的Map*/ public static Map<ImageView, String> mImageViewMap = Collections.synchronizedMap(new HashMap<ImageView, String>()); private ExecutorService executorService; /緩存大小10MiB/ private static int mMemCacheMaxSize = 10 1024 1024; /**LruCache緩存圖片/ private static LruCache<String, byte[]> mMemLruCache; /版本號*/ private static int mAppVersion = 1; /硬盤緩存50M/ private static int mDiskCacheMaxSize = 50 1024 1024; /**硬盤緩存對象/ private static DiskLruCache mDiskLruCache; /是否要初始化*/ private static boolean mCacheInit = false; private static final int DISK_CACHE_COUNT = 1; /GifLoader對象/ private static GifLoader loader; /**默認一張圖片的id/ final int default_image_id = R.drawable.icon_app_normal;/*構造對象/ private GifLoader(Context context) { executorService = Executors.newFixedThreadPool(2); initCaches(context); }
/*單例模式/ public synchronized static GifLoader getInstance(Context context) { if (loader == null) { loader = new GifLoader(context); } return loader; }
/*在控件上展示圖片/ public void displayImage(String url, GifImageView imageView, boolean isGif) { try { if (new File(url).exists()) { imageView.setImageDrawable(new GifDrawable(url)); return; } } catch (Exception e) { }
mImageViewMap.put(imageView, url); byte[] data = mMemLruCache.get(url); if (data != null) { try { imageView.setImageDrawable(new GifDrawable(data)); } catch (Exception e) { e.printStackTrace(); imageView.setImageResource(default_image_id); } } else { queuePhoto(url, imageView); imageView.setImageResource(default_image_id); }
}
private void queuePhoto(String url, GifImageView imageView) { PhotoToLoad photoToLoad = new PhotoToLoad(url, imageView); executorService.submit(new PhotosLoader(photoToLoad)); }
/*此方法待優化以防止內存溢出 先從文件里面讀取,沒有的話再到網上下載/ private byte[] getBitmap(String url) { Snapshot cacheEntry = null; try { cacheEntry = mDiskLruCache.get(CacheHelper.UriToDiskLruCacheString(url)); } catch (Exception e) { e.printStackTrace(); }
byte[] image = null;
if (cacheEntry != null) { image = inputStreamToByteArray(cacheEntry.getInputStream(0), (int) cacheEntry.getLength(0)); mMemLruCache.put(url, image); } try { if (image != null) {
return image; } else { URL imageUrl = new URL(url); HttpURLConnection con = (HttpURLConnection) imageUrl.openConnection(); con.setConnectTimeout(30000); con.setReadTimeout(30000); con.setInstanceFollowRedirects(true); InputStream is = con.getInputStream(); image = inputStreamToByteArray(is, 8096); if (image != null) {
try { Editor editor = mDiskLruCache.edit(CacheHelper.UriToDiskLruCacheString(url)); if (editor != null) { if (CacheHelper.writeByteArrayToEditor(image, editor)) { mDiskLruCache.flush(); editor.commit(); } else { editor.abort(); } } } catch (Exception e) { e.printStackTrace(); }
mMemLruCache.put(url, image); } }
} catch (FileNotFoundException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
return image; }
private class PhotosLoader implements Runnable { private PhotoToLoad photoToLoad;
public PhotosLoader(PhotoToLoad photoToLoad) { super(); this.photoToLoad = photoToLoad; }
@Override public void run() { /*下載前檢查imageview是否被復用/ if (imageViewReused(photoToLoad)) { return; } byte[] bm = getBitmap(photoToLoad.url);
/*下載完畢后再次檢查imageview是否被復用/ if (imageViewReused(photoToLoad)) { return; } DisplayImageRunnable displayImageRunnable = new DisplayImageRunnable(bm, photoToLoad); Activity a = (Activity) photoToLoad.imageView.getContext(); a.runOnUiThread(displayImageRunnable);
}
}
boolean imageViewReused(PhotoToLoad photoToLoad) { String tag = mImageViewMap.get(photoToLoad.imageView); /*代表imageviews map中存放的imageview對應的value值已經被覆蓋掉,也就是重用了/ if (tag == null || !tag.equals(photoToLoad.url)) { return true; } else { return false; }
}
private class DisplayImageRunnable implements Runnable { private byte[] data; private PhotoToLoad photoToLoad;
public DisplayImageRunnable(byte[] data, PhotoToLoad photoToLoad) { super(); this.data = data; this.photoToLoad = photoToLoad; }
@Override public void run() { if (imageViewReused(photoToLoad)) { return; } if (data != null) { try { photoToLoad.imageView.setImageDrawable(new GifDrawable(data)); } catch (Exception e) { e.printStackTrace(); photoToLoad.imageView.setImageResource(default_image_id); } } else { photoToLoad.imageView.setImageResource(default_image_id); }
} }
private class PhotoToLoad { public String url; public GifImageView imageView;
public PhotoToLoad(String url, GifImageView imageView) { super(); this.url = url; this.imageView = imageView; }
}
private void initCaches(Context context) { if (!mCacheInit) { mMemLruCache = new LruCache<String, byte[]>(mMemCacheMaxSize) { protected int sizeOf(String key, byte[] value) { return value.length; } }; File diskCacheDir = CacheHelper.getDiskCacheDir(context, "imagecache"); try { mDiskLruCache = DiskLruCache.open(diskCacheDir, mAppVersion, DISK_CACHE_COUNT, mDiskCacheMaxSize); } catch (IOException ignored) { } mCacheInit = true; } }
private byte[] inputStreamToByteArray(InputStream is, int size) { ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); byte[] buffer = new byte[size];
int len = 0; try { while ((len = is.read(buffer)) != -1) { byteBuffer.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); }
buffer = byteBuffer.toByteArray(); return buffer; } }</pre>