Picasso源码解析(本文基于Picasso2.4.0版本)
Picasso加载图片最简单的调用方法是
Picasso.with(mContext).load(url).into(iv);
我们一起来看看这三个方法里面做了什么
方法解析
1.with
这个方法首先会返回一个单例的Picasso对象(里面用了两个判断一把锁的单例模式)
public static Picasso with(Context context) {
if(singleton == null) {
Class var1 = Picasso.class;
synchronized(Picasso.class) {
if(singleton == null) {
singleton = (new Picasso.Builder(context)).build();
}
}
}
return singleton;
}
如果是第一次创建,会对Picasso进行初始化,主要的有Cache,线程池,downloader,Dispatcher
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, stats, debugging);
}
}
(1) Cache:是一个LruCache 他的最大缓存大小大约是15%(通过下面的方法计算的)
static int calculateMemoryCacheSize(Context context) {
ActivityManager am = getService(context, ACTIVITY_SERVICE);
boolean largeHeap = (context.getApplicationInfo().flags & FLAG_LARGE_HEAP) != 0;
int memoryClass = am.getMemoryClass();
if (largeHeap && SDK_INT >= HONEYCOMB) {
memoryClass = ActivityManagerHoneycomb.getLargeMemoryClass(am);
}
// Target ~15% of the available heap.
return 1024 * 1024 * memoryClass / 7;
}
(2) 线程池:会根据不同的网络状态来改变核心线程的数量(动态设置线程数量的代码在下面,可以作为以后封装线程池的参考)
void adjustThreadCount(NetworkInfo info) {
if (info == null || !info.isConnectedOrConnecting()) {
setThreadCount(DEFAULT_THREAD_COUNT);
return;
}
switch (info.getType()) {
case ConnectivityManager.TYPE_WIFI:
case ConnectivityManager.TYPE_WIMAX:
case ConnectivityManager.TYPE_ETHERNET:
setThreadCount(4);
break;
case ConnectivityManager.TYPE_MOBILE:
switch (info.getSubtype()) {
case TelephonyManager.NETWORK_TYPE_LTE: // 4G
case TelephonyManager.NETWORK_TYPE_HSPAP:
case TelephonyManager.NETWORK_TYPE_EHRPD:
setThreadCount(3);
break;
case TelephonyManager.NETWORK_TYPE_UMTS: // 3G
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_EVDO_B: