Picasso(毕加索)框架 学习笔记

来源:互联网 发布:ms sql server 2012 编辑:程序博客网 时间:2024/04/27 21:06

Picasso(毕加索)框架 学习笔记
By 吴小博

参考文献
http://www.bkjia.com/Androidjc/1004886.html
http://blog.csdn.net/hb308102796/article/details/43637865
http://www.kuqin.com/shuoit/20151023/348630.html
http://blog.csdn.net/sggdjfkf147896325/article/details/51967856

一 什么是Picasso:
强大的图片下载和缓存的第三方库

官网: http://square.github.io/picasso/

二 基本使用

1.Picasso的基本用法:
将Picasso添加进项目后,要使用它非常简单,只需要一行代码就能搞定:

Picasso.with(context).load(imageUrl).into(imageView);

短短的一行代码为我们解决了很多问题:
• 自动将图像缓存在本地
• 通过图片压缩转换以减少内存消耗
• 自动处理了ImageView的回收,即自动取消不在视野范围内的ImageView视图资源的加载;
2.适配器:适配器自动发现和重用以前取消的下载:

    @Override     public void getView(int position, View   convertView, ViewGroup parent) {      SquaredImageView view = (SquaredImageView) convertView;      if (view == null) {        view = new SquaredImageView(context);      }      String url = getItem(position);      Picasso.with(context).load(url).into(view);    }

3.图像格式转换:很多时候需要将图片进行格式转换或者剪裁以节省内存或者达到我们的布局效果:
剪裁大小:
Picasso.with(context).load(imageUrl).resize(50,50).centerCrop().into(imageView);

 public calss myTransformation implements Transformation{        @Overrride        public Bitmap transform(Bitmap source){            //对source实现自定义裁剪        }        @Override        public String key(){            return "square()";        }    }

4.占位符图片:所谓的占位符图像即当图片未正常显示时默认的图片,通过placeholder()设置,Picasso也支持设置图片显示错误时显示的默认图片,通过error()设置:

    Picasso.wint(context).load(imageUrl).placeholder(R.drawable.image_placeholder).error(R.drawable.image_error_placeholder).into(imageView);

5.载入本地资源:除了通过网络下载图片,Picasso也可以载入本地图片资源:

Picasso.with(context).load(R.drawable.icon).into(imageView);    Picasso.with(context).load("file:///android_asset/Adnroid.png").into(imageView);Picasso.wiht(context).load(new File(...)).into(imageView);

6.调试:为了方便调试,你可以通过调用Picasso的setIndicatiorEnabled(true);可以让不同来源的图片显示一个不同的色彩标记;

三 了解基本原理

了解几个图片缓存通用的概念:
(1) RequestManager:请求生成和管理模块
(2) Engine:引擎部分,负责创建任务(获取数据),并调度执行
(3) GetDataInterface:数据获取接口,负责从各个数据源获取数据。
比如 MemoryCache 从内存缓存获取数据、DiskCache 从本地缓存获取数据,下载器从网络获取数据等。
(4) Displayer:资源(图片)显示器,用于显示或操作资源。
比如 ImageView,这几个图片缓存都不仅仅支持 ImageView,同时支持其他 View 以及虚拟的 Displayer 概念。
(5) Processor 资源(图片)处理器
负责处理资源,比如旋转、压缩、截取等。
以上概念的称呼在不同图片缓存中可能不同,比如 Displayer 在 ImageLoader 中叫做 ImageAware,在 Picasso 和 Glide 中叫做 Target。

Picasso 设计及优点
这里写图片描述
1. 总体设计及流程
上面是 Picasso 的总体设计图。整个库分为 Dispatcher,RequestHandler 及 Downloader,PicassoDrawable 等模块。
Dispatcher 负责分发和处理 Action,包括提交、暂停、继续、取消、网络状态变化、重试等等。
简单的讲就是 Picasso 收到加载及显示图片的任务,创建 Request 并将它交给 Dispatcher,Dispatcher 分发任务到具体 RequestHandler,任务通过 MemoryCache 及 Handler(数据获取接口) 获取图片,图片获取成功后通过 PicassoDrawable 显示到 Target 中。
需要注意的是上面 Data 的 File system 部分,Picasso 没有自定义本地缓存的接口,默认使用 http 的本地缓存,API 9 以上使用 okhttp,以下使用 Urlconnection,所以如果需要自定义本地缓存就需要重定义 Downloader。

  1. Picasso 优点
    (1) 自带统计监控功能
    支持图片缓存使用的监控,包括缓存命中率、已使用内存大小、节省的流量等。
    (2) 支持优先级处理
    每次任务调度前会选择优先级高的任务,比如 App 页面中 Banner 的优先级高于 Icon 时就很适用。
    (3) 支持延迟到图片尺寸计算完成加载
    (4) 支持飞行模式、并发线程数根据网络类型而变
    手机切换到飞行模式或网络类型变换时会自动调整线程池最大并发数,比如 wifi 最大并发为 4, 4g 为 3,3g 为 2。
    这里 Picasso 根据网络类型来决定最大并发数,而不是 CPU 核数。
    (5) “无”本地缓存
    无”本地缓存,不是说没有本地缓存,而是 Picasso 自己没有实现,交给了 Square 的另外一个网络库 okhttp 去实现,这样的好处是可以通过请求 Response Header 中的 Cache-Control 及 Expired 控制图片的过期时间。

四 特性
先说一下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之间的关联罢了。

0 0