图片加载库 Picasso 的使用
来源:互联网 发布:php注册页面代码 编辑:程序博客网 时间:2024/05/17 03:48
Picasso
背景:picasso是Square公司出的一款图片加载框架,能够解决我们在Android开发中加载图片时遇到的诸多问题,比如OOM,图片错位等,问题主要集中在加载图片列表时,因为单张图片加载谁都会写。如果我们想在ListView或者GridView或者RecyclerView中加载图片墙,那么这个时候对原图片的二次处理就显得非常重要了,否则就会出现我们上文说的OOM或者图片错位等。不过,如果你使用了Picasso来加载图片的话,那么所有问题都会变得很简单。
基本使用
- 加载网络图片
Picasso.with(this).load("http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg").into(iv);
- 对网络图片裁剪
Picasso.with(this).load("http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg") .resize(200,200) .into(iv);//注意这里的200表示200px,如果你想在resize时指定dp,可以使用如下方法Picasso.with(this).load("http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg") .resizeDimen(R.dimen.iv_width,R.dimen.iv_height) .into(iv);
- 缩放模式
Picasso.with(this).load("http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg") .resizeDimen(R.dimen.iv_width,R.dimen.iv_height) .centerCrop() .into(iv);
- 默认图
Picasso.with(this).load("http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg") //占位图,图片加载出来之前显示的默认图片 .placeholder(R.mipmap.ic_launcher) //错误图,图片加载出错时显示的图片 .error(R.mipmap.ic_launcher) .into(iv);
- 裁剪,高斯模糊
Picasso.with(this).load("http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg") .transform(transformation) .into(iv);
- 查看图片从哪里加载
Picasso picasso = Picasso.with(this); //开启指示器 picasso.setIndicatorsEnabled(true); picasso.load("http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg") .into(iv);
缓存
默认缓存位置:data/data/packagename/cache
缓存方式:Disk 和 Memory
缓存策略:
NO_CACHE:表示处理请求的时候跳过检查内存缓存
NO_STORE: 表示请求成功之后,不将最终的结果存到内存
with(this).load(URL) .placeholder(R.drawable.default_bg) .error(R.drawable.error_iamge) .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE) //禁止内存缓存 .into(mBlurImage);
磁盘缓存:
NO_CACHE: 表示处理请求的时候跳过处理磁盘缓存
NO_STORE: 表示请求成功后,不将结果缓存到Disk,但是这个只对OkHttp有效。
OFFLINE: 这个就跟 上面两个不一样了,如果networkPolicy方法用的是这个参数,那么
Picasso会强制这次请求从缓存中获取结果,不会发起网络请求,不管缓存中能否获取到结果。
with(this).load(URL) .placeholder(R.drawable.default_bg) .error(R.drawable.error_iamge) .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE)//跳过内存缓存 .networkPolicy(NetworkPolicy.NO_CACHE)//跳过磁盘缓存 .into(mBlurImage);
默认缓存位置:
static Downloader createDefaultDownloader(Context context) { try { Class.forName("com.squareup.okhttp.OkHttpClient"); return OkHttpLoaderCreator.create(context); } catch (ClassNotFoundException ignored) { } return new UrlConnectionDownloader(context); }
自定义下载器
Picasso picasso = new Picasso.Builder(this) .downloader(new OkHttp3Downloader(this.getExternalCacheDir())) .build(); Picasso.setSingletonInstance(picasso); picasso.load("http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg").into(iv);
Tag管理请求
cancelTag(Object tag) 取消设置了给定tag的所有请求
pauseTag(Object tag) 暂停设置了给定tag 的所有请求
resumeTag(Object tag) resume 被暂停的给定tag的所有请求
Adapter中添加如下代码:
Picasso.with(this).load(mData.get(position)) .placeholder(R.drawable.default_bg) .error(R.drawable.error_iamge) .tag("PhotoTag") .into(holder.mImageView);
Activity中为RecyclerView添加滑动监听
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { final Picasso picasso = Picasso.with(MainActivity.this); if (newState == SCROLL_STATE_IDLE) { picasso.resumeTag("PhotoTag"); } else { picasso.pauseTag("PhotoTag"); } } });
Activity结束的时候,清除tag
@Override protected void onDestroy() { super.onDestroy(); Picasso.with(this).cancelTag("PhotoTag"); }
线程池
PicassoExecutorService:默认3个线程
也可以自定义线程池
源码分析
通过Builder模式创建实例
1.Picasso.Builder build
/** Start building a new {@link Picasso} instance. */public Builder(Context context) { if (context == null) { throw new IllegalArgumentException("Context must not be null."); } this.context = context.getApplicationContext();}private Downloader downloader;private ExecutorService service;private Cache cache;private Listener listener;private RequestTransformer transformer;private List<RequestHandler> requestHandlers;private Bitmap.Config defaultBitmapConfig;/** Create the {@link Picasso} instance. */public Picasso build() { Context context = this.context; // 为这一系列变量进行默认初始化 // Downloader执行实际的下载业务,返回Response if (downloader == null) { downloader = Utils.createDefaultDownloader(context); } // 内存缓存,可以看到默认的是LruCache if (cache == null) { cache = new LruCache(context); } // 线程池,执行网络请求的地方 if (service == null) { service = new PicassoExecutorService(); } // request发送前进行处理 if (transformer == null) { transformer = RequestTransformer.IDENTITY; } // 用以统计 Stats stats = new Stats(cache); // 进行Request以及Response的转发 Dispatcher dispatcher = new Dispatcher(context, service, HANDLER, downloader, cache, stats); // 创建一个Picasso return new Picasso(context, dispatcher, cache, listener, transformer, requestHandlers, stats, defaultBitmapConfig, indicatorsEnabled, loggingEnabled);}
2. Picasso#load
public RequestCreator load(String path) { if (path == null) { return new RequestCreator(this, null, 0); } if (path.trim().length() == 0) { throw new IllegalArgumentException("Path must not be empty."); } return load(Uri.parse(path));}public RequestCreator load(Uri uri) { return new RequestCreator(this, uri, 0);}
这里创建一个RequestCreator
private final Picasso picasso;private final Request.Builder data;RequestCreator(Picasso picasso, Uri uri, int resourceId) { if (picasso.shutdown) { throw new IllegalStateException( "Picasso instance already shut down. Cannot submit new requests."); } this.picasso = picasso; this.data = new Request.Builder(uri, resourceId, picasso.defaultBitmapConfig);}
data对应创建一个Request的Builder,这个Request中封装了了相应的请求信息,传入了请求加载图片的URI,已经resourceId,以及默认显示图片的配置信息。
进而一般调用into将图片加载到相应的控件中。
RequestCreator#into
// RequestCreator.javapublic void into(ImageView target) { into(target, null);}public void into(ImageView target, Callback callback) { long started = System.nanoTime(); // 盘算是否是在主线程,如果不是则会抛出异常 checkMain(); if (target == null) { throw new IllegalArgumentException("Target must not be null."); } // 判断reqeust是否合法,即存在URI或者对应的resId,否则会取消该请求 if (!data.hasImage()) { picasso.cancelRequest(target); if (setPlaceholder) { setPlaceholder(target, getPlaceholderDrawable()); } return; } // 判断是否需要延期执行 if (deferred) { // 判断是否已经设置了宽高大小 if (data.hasSize()) { throw new IllegalStateException("Fit cannot be used with resize."); } // 获取目标控件的宽高参数 int width = target.getWidth(); int height = target.getHeight(); // 表示当前控件并未加载到界面上(宽或高为0) if (width == 0 || height == 0) { if (setPlaceholder) { setPlaceholder(target, getPlaceholderDrawable()); } // 生成DeferredRequestCreator,加入相应队列进行处理 picasso.defer(target, new DeferredRequestCreator(this, target, callback)); return; } // 设置Request.Builder中的宽高参数大小 data.resize(width, height); } // 创建Request Request request = createRequest(started); // 获取request对应的key String requestKey = createKey(request); // 根据策略判断是够需要跳过读取MemoryCache if (shouldReadFromMemoryCache(memoryPolicy)) { // 尝试从MemoryCache中获取Bitmap // 根据Requeskey来获取相应的Bitmap Bitmap bitmap = picasso.quickMemoryCacheCheck(requestKey); if (bitmap != null) { // 如果从MemoryCache中获取到相应的bitmap,则取消request picasso.cancelRequest(target); // 设置图片 setBitmap(target, picasso.context, bitmap, MEMORY, noFade, picasso.indicatorsEnabled); if (picasso.loggingEnabled) { log(OWNER_MAIN, VERB_COMPLETED, request.plainId(), "from " + MEMORY); } // 调用回调callback的onSuccess函数 if (callback != null) { callback.onSuccess(); } return; } } // 如果从MemoryCache获取图片失败,或者根据缓存策略直接跳过读取MemoryCache,则设置默认图片 if (setPlaceholder) { setPlaceholder(target, getPlaceholderDrawable()); } // 创建ImageViewAction,Action里面包含了一次请求所需要的所有信息 Action action = new ImageViewAction(picasso, target, request, memoryPolicy, networkPolicy, errorResId, errorDrawable, requestKey, tag, callback, noFade); // 将action入队列 picasso.enqueueAndSubmit(action);}
附一张流程图:
相关文章:
http://blog.csdn.net/woliuyunyicai/article/details/51417839
- 图片加载库 Picasso 的使用
- 使用Picasso加载图片
- 使用Picasso加载图片
- 使用Picasso加载图片
- 使用picasso加载图片
- Android框架 加载图片 库 Picasso 的使用简介
- 图片加载框架Picasso的使用
- Picasso网络图片加载框架的使用
- 使用Picasso进行网络图片的加载
- 使用Picasso进行网络图片的加载
- Picasso网络图片加载框架的使用
- Picasso图片加载器的简单使用
- Picasso图片加载器的简单使用
- 图片加载框架 --Picasso 的基本使用
- Picasso 图片加载库
- 使用Picasso加载图片记录
- 图片加载之Picasso使用
- picasso图片加载的优缺点
- windows 下 Anaconda 安装 TensorFlow
- Linux-文件I/O小结
- D脑学院JavaEE 高并发高可用高性能架构设计VIP高级课程
- 一图读懂十一月创投趋势,百度成月度最活跃大公司 | 藏宝图
- 苏宁减持阿里股票获利32亿;京东物流宣称已盈利;三星去年研发投入143亿美元丨价值早报
- 图片加载库 Picasso 的使用
- django中admin管理的使用和配置
- 【转】Mask-RCNN技术解析
- java 线程的几种状态
- Backbone入门指南(三):Events(事件管理)
- 堆和栈的区别
- 在kaldi工具包使用小数字语料库创建一个简单的ASR系统(番外篇)
- 高性能网站建设指南——网站优化的14条建议
- 2017 前端大事件和趋势回顾,2018 何去何从?