Android异步加载网络图片,加载PNG图片时,透明度有时候会被变成黑色。
我写了一个工具类,用于网络加载图片,并显示图片。如果之前加载过该图片,则显示缓存的图片,不用每次都从网络获取。
缓存图片用一个SoftReference来存储,SoftReference是软引用,会在内存不够用时,清楚掉该缓存,不会导致内存泄露的问题。
import java.io.IOException; import java.io.InputStream; import java.lang.ref.SoftReference; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Message; import android.widget.ImageView; /** * 异步加载图片 * 创建时间:2015-8-17 上午10:43:14 * @author Miaozz. * */ public class AsyncImageLoader { public static HashMap<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>(); public AsyncImageLoader() { if(imageCache == null){ imageCache = new HashMap<String, SoftReference<Drawable>>(); } } /** * * @param clearImageCache 为true则清除缓存 */ public AsyncImageLoader(boolean clearImageCache) { if(clearImageCache){ imageCache = new HashMap<String, SoftReference<Drawable>>(); } } /** * 异步加载图片,只加载一次 * @param imageUrl * @param imageCallback * @return */ public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) { final Handler handler = new Handler() { @Override public void handleMessage(Message message) { imageCallback.imageLoaded((Drawable) message.obj, imageUrl); } }; if (imageCache.containsKey(imageUrl)) { SoftReference<Drawable> softReference = imageCache.get(imageUrl); Drawable drawable = softReference.get(); if (drawable != null) { Message message = handler.obtainMessage(0, drawable); handler.sendMessage(message); return drawable; } } new Thread() { @Override public void run() { Drawable drawable = loadImageFromUrl(imageUrl); imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); Message message = handler.obtainMessage(0, drawable); handler.sendMessage(message); } }.start(); return null; } public static Drawable loadImageFromUrl(String url) { Drawable d = null ; if(url.startsWith("http")) { try { InputStream is = (InputStream) new URL(url).openConnection().getContent(); d = Drawable.createFromStream(is, "src"); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return d; } public interface ImageCallback { public void imageLoaded(Drawable imageDrawable, String imageUrl); } /** * 根据url异步获取图片信息 * @param imageUrl * @param againCount 重试次数 * @param callback * @return */ public void loadDrawableFromUrl(final String imageUrl,final int tryAgainCount, final ImageCallback callback) { if(!StringUtil.isEmpty(imageUrl)) { final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { callback.imageLoaded((Drawable) msg.obj,imageUrl); } }; new Thread() { public void run() { Drawable drawable = loadImageFromUrl(imageUrl); int num = 1; while (num <= tryAgainCount && drawable == null) { drawable = loadImageFromUrl(imageUrl); num++; } handler.sendMessage(handler.obtainMessage(0, drawable)); }; }.start(); } } /** * 异步加载图片,失败重试3次 * @param imageUrl * @param callback */ public void loadDrawableFromUrl(final String imageUrl,final ImageCallback callback) { loadDrawableFromUrl(imageUrl, 3, callback); } /** * 异步加载并显示图片,失败显示默认图片 * @param iv * @param imageUrl * @param defaultImgRes */ public void showDrawableFromUrl(final ImageView iv,final String imageUrl,final int defaultImgRes) { if(!StringUtil.isEmpty(imageUrl)) { final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { Drawable drawable = (Drawable) msg.obj; if(drawable != null) { iv.setImageDrawable(drawable); } else { iv.setImageResource(defaultImgRes); } } }; new Thread() { public void run() { Drawable drawable = loadImageFromUrl(imageUrl); int num = 1; while (num <= 3 && drawable == null) { drawable = loadImageFromUrl(imageUrl); num++; } handler.sendMessage(handler.obtainMessage(0, drawable)); }; }.start(); } } /** * 清除缓存 */ public static void clearImgCache() { if(imageCache != null) { imageCache.clear(); imageCache = null; } } }
AsyncImageLoader asyncImageLoader = new AsyncImageLoader(); asyncImageLoader.loadDrawable(imageUrl, new ImageCallback() { @Override public void imageLoaded(Drawable imageDrawable, String imageUrl) { if(imageDrawable != null) { iv.setImageDrawable(imageDrawable); } } });
if (imageCache.containsKey(imageUrl)) 这里是判断是否在缓存中存在该Url的图片,有的话,则直接返回,不需要再从网络中再去读取图片。
在退出的时候,可以调用clearImgCache手动清除缓存。