标签: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