UniversalImageLoader源码解读01-用来显示图片的ImageAware
来源:互联网 发布:js条件公式编辑器 编辑:程序博客网 时间:2024/05/18 02:09
Android平台下有一个著名的图片加载框架叫UniversalImageLoader,这个框架经过几次重构才有今天,有良好的扩展性。如果你曾经在ListView中加载图片出现过图片错乱,如果你曾经因加载图片过多而遇到OOM,那么你应该考虑使用UniversalImageLoader了。
UniversalImageLoader支持二级缓存,内存+磁盘缓存,图片一旦从网络下载后会保存在磁盘缓存里并缓存到内存,这样下次就不会去网络上重新下载,并且内存中如果存在就不会去磁盘上加载,在有限的内存设备上,这种方法增加了内存的换入换出操作,但是总的来说比烦人的OOM要好得多。
本人使用的版本 Version name 1.9.4 Version code 39
为了能够看懂UniversalImageLoader的源码,以下内容你必须知道怎么回事,否则读源码会有困难。本文假定读者有基本的Android控件编程能力。
1) Java多线程的 Executor, 以及ExecutorService, WeakReference如何使用(网上自己去查)
2) 如何使用 UniversalImageLoader(Sample code里有)
解读源码是一件很痛苦的事,因为有时候我们明明知道整个项目是如何工作的,结构如何等等,但是真要是说明白却不知道从哪里下手,在此本人试图说清,欢迎拍砖
下面从包的级别开始,从外层到最核心的代码
com.nostra13.universalimageloader.core.imageaware 封装了图片组件,它将使用图片的控件抽象成 ImageAware,
ViewAware实现了ImageAware接口, ImageViewAware继承ViewAware, NonViewAware也实现了ImageAware接口 ViewAware的接口定义如下:
/* 理解UniversalImageLoader最好的方式就是先去搞清楚如何使用,然后去看每个包下面的接口, 因为UIL充分利用了接口进行抽象,封装了变化,实现了很好的可扩展性。为了方便说明,这里假定是ImageView的一个抽象,定义非常简单*/public interface ImageAware {int getWidth(); //获取ImageView的宽度int getHeight(); //获取ImageView的高度ViewScaleType getScaleType();//获取ImageView的缩放类型View getWrappedView();// 这个就是组件包装的View,通常是个ImageView,当然也可以是其他的Viewboolean isCollected();// 判断View是否被回收,后面会解释int getId();boolean setImageDrawable(Drawable drawable);// 给包装的View设置图片boolean setImageBitmap(Bitmap bitmap);} // 给包装的View设置图片
/* 这个抽象类实现了大部分方法,而把设置图片的工作留给子类*/
public abstract class ViewAware implements ImageAware {public static final String WARN_CANT_SET_DRAWABLE = "Can't set a drawable into view. You should call ImageLoader on UI thread for it.";public static final String WARN_CANT_SET_BITMAP = "Can't set a bitmap into view. You should call ImageLoader on UI thread for it.";protected Reference<View> viewRef;//这就是为什么isCollected方法的由来protected boolean checkActualViewSize;public ViewAware(View view) {this(view, true);}public ViewAware(View view, boolean checkActualViewSize) {if (view == null) throw new IllegalArgumentException("view must not be null");this.viewRef = new WeakReference<View>(view);//采用弱引用包装,这样做会为Bitmap的缓存提供方便,如果被回收了,那么Bitmap或许没必要缓存了this.checkActualViewSize = checkActualViewSize;//尽量获取实际的View宽高,是尽量,如果获取不到,那就取布局参数的宽高}@Overridepublic int getWidth() {View view = viewRef.get();if (view != null) {final ViewGroup.LayoutParams params = view.getLayoutParams();int width = 0;if (checkActualViewSize && params != null && params.width != ViewGroup.LayoutParams.WRAP_CONTENT) {width = view.getWidth(); // Get actual image width}if (width <= 0 && params != null) width = params.width; // Get layout width parameterreturn width;}return 0;}@Overridepublic int getHeight() {View view = viewRef.get();if (view != null) {final ViewGroup.LayoutParams params = view.getLayoutParams();int height = 0;if (checkActualViewSize && params != null && params.height != ViewGroup.LayoutParams.WRAP_CONTENT) {height = view.getHeight(); // Get actual image height}if (height <= 0 && params != null) height = params.height; // Get layout height parameterreturn height;}return 0;}@Overridepublic ViewScaleType getScaleType() {return ViewScaleType.CROP;}@Overridepublic View getWrappedView() {return viewRef.get();// 可能为null}@Overridepublic boolean isCollected() {return viewRef.get() == null;}@Overridepublic int getId() {View view = viewRef.get();return view == null ? super.hashCode() : view.hashCode();}@Overridepublic boolean setImageDrawable(Drawable drawable) {if (Looper.myLooper() == Looper.getMainLooper()) {View view = viewRef.get();if (view != null) {setImageDrawableInto(drawable, view);return true;}} else {L.w(WARN_CANT_SET_DRAWABLE);}return false;}@Overridepublic boolean setImageBitmap(Bitmap bitmap) {if (Looper.myLooper() == Looper.getMainLooper()) {View view = viewRef.get();if (view != null) {setImageBitmapInto(bitmap, view);return true;}} else {L.w(WARN_CANT_SET_BITMAP);}return false;}protected abstract void setImageDrawableInto(Drawable drawable, View view);protected abstract void setImageBitmapInto(Bitmap bitmap, View view);}
- UniversalImageLoader源码解读01-用来显示图片的ImageAware
- UniversalImageLoader源码解读02-图片处理和显示
- UniversalImageLoader源码解读03-一些无关紧要的小类
- UniversalImageLoader源码解读04-内存缓存
- UniversalImageLoader源码解读05-磁盘缓存
- UniversalImageLoader源码解读06-任务调度
- 使用universalimageloader图片加载框架,正确加载却无法显示图片问题的处理
- UniversalImageLoader源码解读07-内存泄漏和bug
- UniversalImageloader 加载图片模糊问题的解决办法
- UniversalImageLoader不能加载本地图片的解决方法
- Android的图片浏览源码解读
- Universalimageloader图片加载框架缓存本地图片的使用
- UniversalImageLoader 源码笔记(1)
- UniversalImageLoader图片加载
- 关于UniversalImageLoader加载图片时的闪烁问题
- 基于universalimageloader实现的图片加载控件BlurImageView
- 基于universalimageloader实现的图片加载控件BlurImageView
- 自己用来显示Toast的
- uva 10566 Crossed ladders(二分 + 几何)
- listview嵌套listview的替换解决方案(适用于个别情况)
- Java 深拷贝&浅拷贝
- hive学习笔记二:安装
- Invalid command: files\mongoDB\log\log.txt
- UniversalImageLoader源码解读01-用来显示图片的ImageAware
- JAVA环境的JAVA_HOME, PATH 和CLASS_PATH设置
- IOS开发学习-篇外Swift2常用语法-3
- java迭代器和比较器
- WIFI ESP8266的SDK实现的云服务器升级程序
- 堆排序
- 游戏坐标系的理解
- http协议详解
- Spring注解@Resource和@Autowired区别对比