Picasso图片加载框架
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
这两日抽空读了下Picasso的源代码,还是很有收获的。安卓APP开发最头疼的问题之一就是图片解析这块。而Picasso项目几近完美的解决这个问题。为开发者提供了方便。
Picasso.with(context) .load(url).resize(50, 50).centerCrop().into(imageView)
先说一下Picasso特性:
1、动态适配界面上的ImageView大小,自动计算进行缩放。
该功能在源码中的实现原理为:为ImageView设置OnPreDrawListener监听,在OnPreDraw()中,获取界面上ImageView在绘制前的宽高,然后在解析时,进行动态计算SimpleSize,最终解析。详见:RequestCreator.java类的574行。
2、在adapter中使用时,当ImageView被重用时,取消访问之前的图片。
具体实现为,在提交Action时,进行判断,有没有相同的ImageView对应的Action,已放到线程池中,如有,则取消,然后加入新的Action。
详见:Picasso.java类的enqueueAndSubmit(Action action)方法。
3、协同OKhttp、okhttp-urlconnecion自动实现硬盘缓存。
具体实现为,在Picasso进行build时,创建Downloader时,用反射去检测,如果项目集成了okhttp包,则用okhttp包中的类去创建一个OkHttpDownloader.java下载器,如果项目未集成okhttp,则使用自带的UrlConnectionDownloader.java创建。而通过查看okhttp包源代码得知,下载是利用了DiskLruCache的,由此可见Picasso结合okhttp几乎是目前最佳的网络图片解决方案了。
值得学习的部分:
1、图片解析锁。
保证在同一时间,系统只在解析一个图片,防止多线程解析,出现OOM风险,也减少了同一时刻对硬件设备的性能开销。
2、动态判断网络类型,根据网络类型,创建合适的线程池大小。
这里Picasso分的比较细,详见PicassoExecutorService.java中的adjustThreadCount(NetworkInfo info) 方法,为WIFI、4G、3G、2G不同状态,创建了不同的线程池大小。
3、使用Future模式,在adapter中使用时,当ImageView被重用,加载新的图片地址时,取消已加入线程池中的访问请求(正在执行的则执行完)
这里不得不再说一句,我们常用ListView优化,那么有哪些有化的方法呢?对了,除了ViewHolder,还有Picasso这里的取消离开界面的后台请求优化。还有如解析、显示图片的优化,比如最好借助Handler队列,实现同一时间,只解析一张图,只显示一张图。
这里关于ListView还有个问题,就是图片加载错乱的问题,Picasso也已经帮开发者解决了。基本原理就是建立imageview和url之间的关联,在最终显示时,判断imageview的tag是否与该将要显示的图片下载地址相同。不过Picasso这里是建立了imageview和action之间的关联罢了。
另外还有个疑问,为什么使用LruCache对图片数据进行驱逐后,bitmap就能被系统回收呢?并没有recycle啊,GC为什么会回收它?不是说靠GC回收bitmap是无法回收完全的吗?哪位知道还请留言告知,不胜感激!!
三、共同优点
1. 使用简单
都可以通过一句代码可实现图片获取和显示。
2. 可配置度高,自适应程度高
图片缓存的下载器(重试机制)、解码器、显示器、处理器、内存缓存、本地缓存、线程池、缓存算法等大都可轻松配置。
自适应程度高,根据系统性能初始化缓存配置、系统信息变更后动态调整策略。
比如根据CPU 核数确定最大并发数,根据可用内存确定内存缓存大小,网络状态变化时调整最大并发数等。
3. 多级缓存
都至少有两级缓存、提高图片加载速度。
4. 支持多种数据源
支持多种数据源,网络、本地、资源、Assets 等
5. 支持多种Displayer
不仅仅支持ImageView,同时支持其他View 以及虚拟的Displayer 概念。
其他小的共同点包括支持动画、支持transform 处理、获取EXIF 信息等。