首先从调用第一行代码看起
// Trigger the download of the URL asynchronously into the image view.
Picasso.with()
.load(url)
.placeholder(R.drawable.placeholder)
.error(R.drawable.error)
.resizeDimen(R.dimen.list_detail_image_size,R.dimen.list_detail_image_size)
.centerInside()
.tag(context)
.into(holder.image);
很显然是单例模式
public staticPicassowith() {
if(singleton==null) {
synchronized(Picasso.class) {
if(singleton==null) {
if(PicassoProvider.context==null) {
throw newIllegalStateException("context == null");
}
singleton=newBuilder(PicassoProvider.context).build();
}
}
}
returnsingleton;
}
里面还有个PicassoProvider,在这个类里面直接获取的Context
@RestrictTo(LIBRARY)
public final class PicassoProvider extends ContentProvider {
static Context context;
@Override public booleanonCreate() {
context= getContext();
return true;
}
再看通过内部Builder的build方法创建一些默认的内部依赖的类.
/** Create the {
@linkPicasso} instance. */
public Picasso build() {
Context context =this.context;
if(downloader==null) {
downloader=new OkHttp3Downloader(context);//下载器
}
if(cache==null) {
cache=new LruCache(context);//缓存
}
if(service==null) {
service=new PicassoExecutorService();//线程池
}
if(transformer==null) {
transformer= RequestTransformer.IDENTITY;//Request转换
}
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);
}
再看
public RequestCreator load(@NullableString 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));
}
将String转换为Uri,最终调用。生成一个RequestCreator对象。
public RequestCreator load(@NullableUri uri) {
return new RequestCreator(this,uri,0);
}
这个对象存储了请求的基本信息,如果是请求网络则第三个参数为0如果是资源文件则第三个参数就是资源id
public class RequestCreator {
private static final AtomicInteger nextId=newAtomicInteger();
private final Picasso picasso;
private final Request.Builder data;
private boolean noFade;
private boolean deferred;
private boolean setPlaceholder=true;
private int placeholderResId;
private int errorResId;
private int memoryPolicy;
private int networkPolicy;
private Drawable placeholderDrawable;
private Drawable errorDrawable;
private Object tag;
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);
}
再往下看。设置还未下载图片之前占位资源id。
public RequestCreator placeholder(@DrawableRes int placeholderResId) {
if(!setPlaceholder) {//默认这个值为true,如果调用noPlaceholder方法则为false
throw new IllegalStateException("Already explicitly declared as no placeholder.");
}
if(placeholderResId ==0) {
throw new IllegalArgumentException("Placeholder image resource invalid.");
}
if(placeholderDrawable!=null) {
throw new IllegalStateException("Placeholder image already set.");
}
this.placeholderResId= placeholderResId;
return this;
}
同样的设置错误是显示资源Id
/** An error drawable to be used if the request image could not be loaded. */
public RequestCreator error(@DrawableRes int errorResId) {
if(errorResId ==0) {
throw new IllegalArgumentException("Error image resource invalid.");
}
if(errorDrawable!=null) {
throw new IllegalStateException("Error image already set.");
}
this.errorResId= errorResId;
return this;
}
fitz表示要处理下载后的图片要适应图片控件的大小
/*** Attempt to resize the image to fit exactly into the target { @linkImageView}'s bounds. This* will result in delayed execution of the request until the { @linkImageView} has been laid out.*
*Note:This method works only when your target is an {
@linkImageView}.*/
public RequestCreator fit() {
deferred=true;
return this;
}
Tag表示一个类关联当前请求,下面有个警告,说只要tag状态是暂停或者有活动的请求,picasso一直会保持tag的引用,有可能有内存泄露
/*** Assign a tag to this request. Tags are an easy way to logically associate* related requests that can be managed together e.g. paused, resumed,* or canceled.*
* You can either use simple { @linkString} tags or objects that naturally* define the scope