package com.dh.foundation.utils; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.net.http.AndroidHttpClient; import android.os.Build; import android.view.animation.AlphaAnimation; import android.widget.ImageView; import com.dh.foundation.volley.RequestQueue; import com.dh.foundation.volley.VolleyError; import com.dh.foundation.volley.toolbox.BasicNetwork; import com.dh.foundation.volley.toolbox.HttpClientStack; import com.dh.foundation.volley.toolbox.HttpStack; import com.dh.foundation.volley.toolbox.ImageLoader; import com.dh.foundation.volley.patch.ImageDiskBasedCache; import com.dh.foundation.volley.Network; import com.dh.foundation.volley.toolbox.HurlStack; import com.dh.foundation.manager.FoundationManager; import java.io.File; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.Map; /** * ImageView图片请求加载工具类 * Created By: Seal.Wu * Date: 2015/4/14 * Time: 13:58 */ public class ImageNetLoader { private final static String DEFAULT_CACHE_DIR = "volley/image"; private final static String NULL = "null"; private final static BitmapCache imageCache = new BitmapCache(); private final RequestQueue imageRequestQueue = newImageRequestQueue(FoundationManager.getContext(), null); private final ImageLoader imageLoader = new ImageLoader(imageRequestQueue, imageCache); private Map<String, WeakReference<ImageLoader.ImageContainer>> imageContainerMap = new HashMap<>(); private Map<String, WeakReference<BitmapReceiverHolder>> holderMap = new HashMap<>(); /** * 用于存储加载过的ImageView */ private HashMap<ImageViewInfoHolder, WeakReference<ImageView>> imageViews = new HashMap<>(); /** * 当前图片加载器是否有效,能使用,默认有用 */ private boolean enable = true; private final static ImageNetLoader DEFAULT_INSTANCE = new ImageNetLoader(); public ImageLoader getImageLoader() { return imageLoader; } public static BitmapCache getImageCache() { return imageCache; } public static ImageNetLoader getDefault() { return DEFAULT_INSTANCE; } void setEnable(boolean enable) { this.enable = enable; } boolean isEnable() { return enable; } void resumeAllImageViews() { setEnable(true); for (Map.Entry<ImageViewInfoHolder, WeakReference<ImageView>> entry : imageViews.entrySet()) { final ImageView imageView = entry.getValue().get(); final ImageViewInfoHolder key = entry.getKey(); if (imageView != null) { loadImage(imageView, key.url, key.errorImageResId, key.defaultImageResId, key.maxWidth, key.maxHeight); } else { imageViews.remove(key); } } } public void getBitmap(String url, final BitmapReceiver bitmapReceiver, int maxWidth, int maxHigh) { if (url == null) { url = NULL; } DLoggerUtils.i("ImageNetLoader url =========> " + url); final BitmapReceiverHolder bitmapReceiverHolder = new BitmapReceiverHolder(bitmapReceiver); final ImageLoader.ImageContainer imageContainer = getImageLoader().get(url, new ImageLoader.ImageListener() { @Override public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) { if (bitmapReceiverHolder.getBitmapReceiver() != null && response.getBitmap() != null) { bitmapReceiverHolder.getBitmapReceiver().onReceiveBitmap(response.getBitmap(), isImmediate); } } @Override public void onErrorResponse(VolleyError error) { if (bitmapReceiverHolder.getBitmapReceiver() != null) { bitmapReceiverHolder.getBitmapReceiver().onError(error); } DLoggerUtils.e(error); } }, maxWidth, maxHigh); imageContainerMap.put(url, new WeakReference<ImageLoader.ImageContainer>(imageContainer)); holderMap.put(url, new WeakReference<BitmapReceiverHolder>(bitmapReceiverHolder)); } public void getBitmap(final String url, final BitmapReceiver bitmapReceiver) { getBitmap(url, bitmapReceiver, 0, 0); } public void loadImage(final ImageView imageView, final String url) { loadImage(imageView, url, 0, 0); } public void loadImage(final ImageView imageView, final String url, final int errorImageResId, final int defaultImageResId) { loadImage(imageView, url, errorImageResId, defaultImageResId, 0, 0); } /** * 装载图片到视图控件里 * * @param imageView 视图控件 * @param url 图片网络链接地址 * @param errorImageResId 错误图片id * @param defaultImageResId 默认图片id * @param maxWidth 设置显示的最大宽度 * @param maxHigh 设置显示的最大高度 */ public void loadImage(final ImageView imageView, String url, final int errorImageResId, final int defaultImageResId, int maxWidth, int maxHigh) { if (url == null) { url = NULL; } imageView.setTag(url); if (defaultImageResId != 0) { imageView.setImageResource(defaultImageResId); } final ImageViewInfoHolder imageViewInfoHolder = getImageViewInfoHolder(imageView); if (imageViewInfoHolder == null) { /** * 当前ImageView没有持有info信息的时候 */ imageViews.put(new ImageViewInfoHolder(url, defaultImageResId, errorImageResId, maxWidth, maxHigh), new WeakReference<ImageView>(imageView)); } else { /** * 替换info信息 */ imageViewInfoHolder.url = url; imageViewInfoHolder.defaultImageResId = defaultImageResId; imageViewInfoHolder.errorImageResId = errorImageResId; imageViewInfoHolder.maxWidth = maxWidth; imageViewInfoHolder.maxHeight = maxHigh; } /** * 不可用的时候直接pass掉 */ if (!enable) { return; } final String finalUrl = url; getBitmap(url, new BitmapReceiver() { @Override public void onReceiveBitmap(Bitmap bitmap, boolean isImmediate) { if (imageView.getTag().equals(finalUrl)) { imageView.setImageBitmap(bitmap); if (!isImmediate) { AlphaAnimation animation = new AlphaAnimation(0, 1); animation.setDuration(300); imageView.startAnimation(animation); } } } @Override public void onError(Throwable error) { if (errorImageResId != 0 && imageView.getTag().equals(finalUrl)) { imageView.setImageResource(errorImageResId); } } }, maxWidth, maxHigh); } private ImageViewInfoHolder getImageViewInfoHolder(ImageView imageView) { for (Map.Entry<ImageViewInfoHolder, WeakReference<ImageView>> entry : imageViews.entrySet()) { if (imageView.equals(entry.getValue().get())) { return entry.getKey(); } } return null; } public static RequestQueue newImageRequestQueue(Context context, HttpStack stack) { File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR); String userAgent = "volley/0"; try { String packageName = context.getPackageName(); PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0); userAgent = packageName + "/" + info.versionCode; } catch (PackageManager.NameNotFoundException e) { } if (stack == null) { if (Build.VERSION.SDK_INT >= 9) { stack = new HurlStack(); } else { // Prior to Gingerbread, HttpUrlConnection was unreliable. // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); } } Network network = new BasicNetwork(stack); RequestQueue queue = new RequestQueue(new ImageDiskBasedCache(cacheDir), network); queue.start(); return queue; } /** * 结束所有Image的请求 */ public void cancelAll() { for (Map.Entry<String, WeakReference<ImageLoader.ImageContainer>> entry : imageContainerMap.entrySet()) { final ImageLoader.ImageContainer imageContainer = entry.getValue().get(); if (imageContainer != null) { imageContainer.cancelRequest(); } final BitmapReceiverHolder bitmapReceiverHolder = holderMap.get(entry.getKey()).get(); if (bitmapReceiverHolder != null) { bitmapReceiverHolder.setBitmapReceiver(null); } } imageContainerMap.clear(); holderMap.clear(); imageViews.clear(); } /** * 结束指定Image的请求 * * @param url 请求的image的url */ public void cancel(String url) { if (url == null) { url = NULL; } for (Map.Entry<String, WeakReference<ImageLoader.ImageContainer>> entry : imageContainerMap.entrySet()) { if (StringUtils.equals(url, entry.getKey())) { final ImageLoader.ImageContainer imageContainer = entry.getValue().get(); if (imageContainer != null) { imageContainer.cancelRequest(); } final BitmapReceiverHolder bitmapReceiverHolder = holderMap.get(entry.getKey()).get(); if (bitmapReceiverHolder != null) { bitmapReceiverHolder.setBitmapReceiver(null); } imageContainerMap.remove(entry.getKey()); holderMap.remove(entry.getKey()); break; } } } /** * 销毁当前图片加载器 */ public void destroy() { imageRequestQueue.stop(); } static final class BitmapReceiverHolder { private BitmapReceiver bitmapReceiver; public BitmapReceiverHolder(BitmapReceiver bitmapReceiver) { this.bitmapReceiver = bitmapReceiver; } public void setBitmapReceiver(BitmapReceiver bitmapReceiver) { this.bitmapReceiver = bitmapReceiver; } public BitmapReceiver getBitmapReceiver() { return bitmapReceiver; } } /** * Bitmap接收者 */ public interface BitmapReceiver { /** * @param bitmap 接收到的位图 * @param isImmediate 是否是在内存中立即返回 */ void onReceiveBitmap(Bitmap bitmap, boolean isImmediate); /** * 接收位图失败 * * @param error 失败原因 */ void onError(Throwable error); } public static class SimpleBitmapReceiver implements BitmapReceiver { @Override public void onReceiveBitmap(Bitmap bitmap, boolean isImmediate) { } @Override public void onError(Throwable error) { } } /** * 待加载图像的ImageView的加载内容信息 */ static class ImageViewInfoHolder { /** * 图像网络地址 */ String url; /** * 默认显示图片资源id */ int defaultImageResId; /** * 加载失败显示图片资源id */ int errorImageResId; /** * 设置显示的最大宽度 */ int maxWidth; /** * 设置显示的最大高度 */ int maxHeight; public ImageViewInfoHolder(String url, int defaultImageResId, int errorImageResId, int maxWidth, int maxHeight) { this.url = url; this.defaultImageResId = defaultImageResId; this.errorImageResId = errorImageResId; this.maxWidth = maxWidth; this.maxHeight = maxHeight; } } }