标签:android 框架 图片加载 imageloader
/** * ImageLoader配置类, * * @author mrsimple */ public class ImageLoaderConfig { /** * 图片缓存配置对象 */ public BitmapCache bitmapCache = new MemoryCache(); /** * 加载图片时的loading和加载失败的图片配置对象 */ public DisplayConfig displayConfig = new DisplayConfig(); /** * 加载策略 */ public LoadPolicy loadPolicy = new SerialPolicy(); /** * */ public int threadCount = Runtime.getRuntime().availableProcessors() + 1; /** * @param count * @return */ public ImageLoaderConfig setThreadCount(int count) { threadCount = Math.max(1, threadCount); return this; } public ImageLoaderConfig setCache(BitmapCache cache) { bitmapCache = cache; return this; } public ImageLoaderConfig setLoadingPlaceholder(int resId) { displayConfig.loadingResId = resId; return this; } public ImageLoaderConfig setNotFoundPlaceholder(int resId) { displayConfig.failedResId = resId; return this; } public ImageLoaderConfig setLoadPolicy(LoadPolicy policy) { if (policy != null) { loadPolicy = policy; } return this; } }
/** * 图片加载类,支持url和本地图片的uri形式加载.根据图片路径格式来判断是网络图片还是本地图片,如果是网络图片则交给SimpleNet框架来加载, * 如果是本地图片那么则交给mExecutorService从sd卡中加载 * .加载之后直接更新UI,无需用户干预.如果用户设置了缓存策略,那么会将加载到的图片缓存起来.用户也可以设置加载策略,例如顺序加载{@see * SerialPolicy}和逆向加载{@see ReversePolicy}. * * @author mrsimple */ public final class SimpleImageLoader { /** SimpleImageLoader实例 */ private static SimpleImageLoader sInstance; /** 网络请求队列 */ private RequestQueue mImageQueue; /** 缓存 */ private volatile BitmapCache mCache = new MemoryCache(); /** 图片加载配置对象 */ private ImageLoaderConfig mConfig; private SimpleImageLoader() { } /** * 获取ImageLoader单例 * * @return */ public static SimpleImageLoader getInstance() { if (sInstance == null) { synchronized (SimpleImageLoader.class) { if (sInstance == null) { sInstance = new SimpleImageLoader(); } } } return sInstance; } /** * 初始化ImageLoader,启动请求队列 * @param config 配置对象 */ public void init(ImageLoaderConfig config) { mConfig = config; mCache = mConfig.bitmapCache; checkConfig(); mImageQueue = new RequestQueue(mConfig.threadCount); mImageQueue.start(); } private void checkConfig() { if (mConfig == null) { throw new RuntimeException( "The config of SimpleImageLoader is Null, please call the init(ImageLoaderConfig config) method to initialize"); } if (mConfig.loadPolicy == null) { mConfig.loadPolicy = new SerialPolicy(); } if (mCache == null) { mCache = new NoCache(); } } public void displayImage(ImageView imageView, String uri) { displayImage(imageView, uri, null, null); } public void displayImage(final ImageView imageView, final String uri, final DisplayConfig config, final ImageListener listener) { BitmapRequest request = new BitmapRequest(imageView, uri, config, listener); // 加载的配置对象,如果没有设置则使用ImageLoader的配置 request.displayConfig = request.displayConfig != null ? request.displayConfig : mConfig.displayConfig; // 添加对队列中 mImageQueue.addRequest(request); } // 代码省略... /** * 图片加载Listener * * @author mrsimple */ public static interface ImageListener { public void onComplete(ImageView imageView, Bitmap bitmap, String uri); } }
public BitmapRequest(ImageView imageView, String uri, DisplayConfig config, ImageListener listener) { mImageViewRef = new WeakReference<ImageView>(imageView); displayConfig = config; imageListener = listener; imageUri = uri; // 设置ImageView的tag为图片的uri imageView.setTag(uri); imageUriMd5 = Md5Helper.toMD5(imageUri); }
/** * 请求队列, 使用优先队列,使得请求可以按照优先级进行处理. [ Thread Safe ] * * @author mrsimple */ public final class RequestQueue { /** * 请求队列 [ Thread-safe ] */ private BlockingQueue<BitmapRequest> mRequestQueue = new PriorityBlockingQueue<BitmapRequest>(); /** * 请求的序列化生成器 */ private AtomicInteger mSerialNumGenerator = new AtomicInteger(0); /** * 默认的核心数 */ public static int DEFAULT_CORE_NUMS = Runtime.getRuntime().availableProcessors() + 1; /** * CPU核心数 + 1个分发线程数 */ private int mDispatcherNums = DEFAULT_CORE_NUMS; /** * NetworkExecutor,执行网络请求的线程 */ private RequestDispatcher[] mDispatchers = null; /** * */ protected RequestQueue() { this(DEFAULT_CORE_NUMS); } /** * @param coreNums 线程核心数 * @param httpStack http执行器 */ protected RequestQueue(int coreNums) { mDispatcherNums = coreNums; } /** * 启动RequestDispatcher */ private final void startDispatchers() { mDispatchers = new RequestDispatcher[mDispatcherNums]; for (int i = 0; i < mDispatcherNums; i++) { mDispatchers[i] = new RequestDispatcher(mRequestQueue); mDispatchers[i].start(); } } public void start() { stop(); startDispatchers(); } /** * 停止RequestDispatcher */ public void stop() { if (mDispatchers != null && mDispatchers.length > 0) { for (int i = 0; i < mDispatchers.length; i++) { mDispatchers[i].interrupt(); } } } /** * 不能重复添加请求 * @param request */ public void addRequest(BitmapRequest request) { if (!mRequestQueue.contains(request)) { request.serialNum = this.generateSerialNumber(); mRequestQueue.add(request); } else { Log.d("", "### 请求队列中已经含有"); } } private int generateSerialNumber() { return mSerialNumGenerator.incrementAndGet(); } } ``` ## RequestDispatcher请求分发 请求Dispatcher,继承自Thread,从网络请求队列中循环读取请求并且执行,也比较简单,直接上源码吧。 ``` final class RequestDispatcher extends Thread { /** * 网络请求队列 */ private BlockingQueue<BitmapRequest> mRequestQueue; /** * @param queue 图片加载请求队列 */ public RequestDispatcher(BlockingQueue<BitmapRequest> queue) { mRequestQueue = queue; } @Override public void run() { try { while (!this.isInterrupted()) { final BitmapRequest request = mRequestQueue.take(); if (request.isCancel) { continue; } // 解析图片schema final String schema = parseSchema(request.imageUri); // 根据schema获取对应的Loader Loader imageLoader = LoaderManager.getInstance().getLoader(schema); // 加载图片 imageLoader.loadImage(request); } } catch (InterruptedException e) { Log.i("", "### 请求分发器退出"); } } /** * 这里是解析图片uri的格式,uri格式为: schema:// + 图片路径。 */ private String parseSchema(String uri) { if (uri.contains("://")) { return uri.split("://")[0]; } else { Log.e(getName(), "### wrong scheme, image uri is : " + uri); } return ""; } }
如果你觉得我写得还行,那就帮我顶个帖吧!Thanks~
教你写Android ImageLoader框架之初始配置与请求调度
标签:android 框架 图片加载 imageloader
原文地址:http://blog.csdn.net/bboyfeiyu/article/details/43195705