在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;
}
}