1.自定义缓存位置
picasso默认缓存位置为 /data/data/应用包名/cache 路径下在这里如果我们实用的是模拟器或者经过root的手机我们可以直接访问该目录接下来我们来从picasso的源码进行分析
首先我们一般调用picasso是这样的
Picasso.with(getApplicationContext())
.load("http://i2.17173cdn.com/i7mz64/YWxqaGBf/tu17173com/20151019/phiDLtbkbFqzitl.jpg")
.transform(transformation)
.into(imageview);
那我们先看第一部Picasso.with(getApplicationContext())在这里发生了什么
public static Picasso with(Context context) {
if (singleton == null) {
synchronized (Picasso.class) {
if (singleton == null) {
singleton = new Builder(context).build();
}
}
}
return singleton;
}
我们从源码看到了2点 1.picasso是单例的 2.picasso的构建是通过Build模式构建的
我们继续看picasso的Build里面发生了什么这里我们取到Builder的源码并去掉一些注释
public static class Builder {
private final Context context;
private Downloader downloader;
private ExecutorService service;
private Cache cache;
private Listener listener;
private RequestTransformer transformer;
private List<RequestHandler> requestHandlers;
private Bitmap.Config defaultBitmapConfig;
private boolean indicatorsEnabled;
private boolean loggingEnabled;
//创建一个新的Builder实例
public Builder(Context context) {
if (context == null) {
throw new IllegalArgumentException("Context must not be null.");
}
this.context = context.getApplicationContext();
}
// 设置bitMap的基本属性
public Builder defaultBitmapConfig(Bitmap.Config bitmapConfig) {
if (bitmapConfig == null) {
throw new IllegalArgumentException("Bitmap config must not be null.");
}
this.defaultBitmapConfig = bitmapConfig;
return this;
}
//设置下载器用于设置下载属性
public Builder downloader(Downloader downloader) {
if (downloader == null) {
throw new IllegalArgumentException("Downloader must not be null.");
}
if (this.downloader != null) {
throw new IllegalStateException("Downloader already set.");
}
this.downloader = downloader;
return this;
}
//设置picasso的下载线程池
public Builder executor(ExecutorService executorService) {
if (executorService == null) {
throw new IllegalArgumentException("Executor service must not be null.");
}
if (this.service != null) {
throw new IllegalStateException("Executor service already set.");
}
this.service = executorService;
return this;
}
//指定用于最新图像的内存缓存。
public Builder memoryCache(Cache memoryCache) {
if (memoryCache == null) {
throw new IllegalArgumentException("Memory cache must not be null.");
}
if (this.cache != null) {
throw new IllegalStateException("Memory cache already set.");
}
this.cache = memoryCache;
return this;
}
//指定监听器(暂时不太明白什么监听)
public Builder listener(Listener listener) {
if (listener == null) {
throw new IllegalArgumentException("Listener must not be null.");
}
if (this.listener != null) {
throw new IllegalStateException("Listener already set.");
}
this.listener = listener;
return this;
}
//给所有请求添加一个请求的变换器用于修改请求信息
public Builder requestTransformer(RequestTransformer transformer) {
if (transformer == null) {
throw new IllegalArgumentException("Transformer must not be null.");
}
if (this.transformer != null) {
throw new IllegalStateException("Transformer already set.");
}
this.transformer = transformer;
return this;
}
//添加请求处理器
public Builder addRequestHandler(RequestHandler requestHandler) {
if (requestHandler == null) {
throw new IllegalArgumentException("RequestHandler must not be null.");
}
if (requestHandlers == null) {
requestHandlers = new ArrayList<RequestHandler>();
}
if (requestHandlers.contains(requestHandler)) {
throw new IllegalStateException("RequestHandler already registered.");
}
requestHandlers.add(requestHandler);
return this;
}
//debug模式控制器
@Deprecated public Builder debugging(boolean debugging) {
return indicatorsEnabled(debugging);
}
//切换是否在图像上显示调试指示器。
public Builder indicatorsEnabled(boolean enabled) {
this.indicatorsEnabled = enabled;
return this;
}
//控制是否打印错误日志(picasso默认是关闭的)
public Builder loggingEnabled(boolean enabled) {
this.loggingEnabled = enabled;
return this;
}
//创建picasso实例
public Picasso build() {
Context context = this.context;
if (downloader == null) {
downloader = Utils.createDefaultDownloader(context);
}
if (cache == null) {
cache = new LruCache(context);
}
if (service == null) {
service = new PicassoExecutorService();
}
if (transformer == null) {
transformer = RequestTransformer.IDENTITY;
}
Stats stats = new Stats(cache);
Dispatcher dispatcher = new Dispatcher(context, service, HANDLER, downloader, cache, stats);
return new Picasso(context, dispatcher, cache, listener, transformer, requestHandlers, stats,
defaultBitmapConfig, indicatorsEnabled, loggingEnabled);
}
}
上面代码有些多不过我们一点一点分析 我们的Build可以说是picasso实例创建的控制器用于创建picasso的实例。
1. 首先我们通过Builder(Context context) 这个构造方法创建了Builder的实例
2. 之后我们通过memoryCache(Cache memoryCache), requestTransformer(RequestTransformer transformer)… 一系列的方法还是返回了Builder自己
3. 最后我们通过build() 方法完成我们的设置并创建picasso的实例
那我们的Builder方法有哪些功能呢 ?
我们可以看到 他可以配置项目有
1. 配置picasso的下载器
2. 配置图片的LruCache
3. 配置picasso的PicassoExecutorService即线程池
4. 配置picasso的RequestTransformer请求转换器
5. 默认picasso的Stats 以及Dispatcher
6. 指定监听器(暂时不太明白什么监听) 提供debug模式控制器 控制是否在图像上显示调试指示器 控制是否打印错误日志(picasso默认是关闭的)
picasso的Builder确实提供了许多优秀以及强大的方法这里我们先只关注跟下载相关的picasso的下载器
我们可以看到:
if (downloader == null) {
downloader = Utils.createDefaultDownloader(context);
}
如果下载器为空的时候picasso的工具包为我们创建了一个默认的Downloader让我们看看Downloader是如何处理下载的
static Downloader createDefaultDownloader(Context context) {
try {
Class.forName("com.squareup.okhttp.OkHttpClient");
return OkHttpLoaderCreator.create(context);
} catch (ClassNotFoundException ignored) {
}
return new UrlConnectionDownloader(context);
}
ok我们可以看到当我们的项目中如果有OkHttp的话picasso会默认创建OkHttp的Downloader如果没有的话picasso会返回HttpURLConnection的Downloader这样的话如果我们使用okhttp会调用okhttp的下载路径 /storage/sdcard/Android/data/应用包名/cache 如果我们想自己定义位置的话我们需要做如下处理
private void loadImageCache() {
final String imageCacheDir = /* 自定义目录 */ + "image";
Picasso picasso = new Picasso.Builder(this).downloader(
new OkHttpDownloader(new File(imageCacheDir))).build();
Picasso.setSingletonInstance(picasso);//必须要有否则上面配置会失效
}
接下来我们在下一篇博客中介绍picasso的其他高级使用