####前言 前面一篇文章簡單的介紹了Picasso的使用,已經整個原始碼呼叫的流程,過了一遍。但是其中還有很多的細節我們並沒有去涉及到。今天在昨天的基礎之上再進行深入。
Picasso物件
前面一篇文章我們是從Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(ivTest)
慢慢深入的,這裡我們也要找個可以深入的物件,就是最重要的Picasso
物件。
因為我們在使用的時候就是直接Picasso.get().***
這樣去呼叫的,所以說我們先了解下Picasso
所有的api,對整個框架的理解,以及對Picasso
更有效率的使用。
####public方法
我們的as很強大,直接左側欄檢視當前類的公用方法.
這裡就把方法一個個介紹下。便於大家理解。
- areIndicatorsEnabled(),setIndicatorsEnabled()
@SuppressWarnings("UnusedDeclaration") public void setIndicatorsEnabled(boolean enabled) {
indicatorsEnabled = enabled;
}
@SuppressWarnings("UnusedDeclaration") public boolean areIndicatorsEnabled() {
return indicatorsEnabled;
}
複製程式碼
用來設定和獲取是否顯示當前載入圖片的方式,上一篇文章有使用過,就是顯示當前圖片是由三級快取中的哪一個載入的。
- cancelRequest 看名字就知道,是直接用來取消請求的。 這裡可以深入下。
public void cancelRequest(@NonNull ImageView view) {
if (view == null) {
throw new IllegalArgumentException("view cannot be null.");
}
cancelExistingRequest(view);
}
void cancelExistingRequest(Object target) {
checkMain();
//前面在載入圖片的時候是會target-action以key-value的方式儲存在targetToAction中,後面我會指出,在哪裡儲存的。這裡直接通過target獲取到action,然後cancel
Action action = targetToAction.remove(target);
if (action != null) {
action.cancel();
dispatcher.dispatchCancel(action);
}
//這裡就比較有意思,因為第一篇文章我們介紹過,如果是`ImageView`的話,很可能會使用fit方法去適配`ImageView`的寬高,就有使用到DeferredRequestCreator,所以這裡要移除
if (target instanceof ImageView) {
ImageView targetImageView = (ImageView) target;
DeferredRequestCreator deferredRequestCreator =
targetToDeferredRequestCreator.remove(targetImageView);
if (deferredRequestCreator != null) {
deferredRequestCreator.cancel();
}
}
}
複製程式碼
- cancelTag,pauseTag,resumeTag 這3個一起說,這3個可以說是批量操作符。可以簡單的看一下。
Picasso.get().load("http://i.imgur.com/DvpvklR.png")
.tag("test")
.into(ivTest)
Picasso.get()
.load("http://i.imgur.com/DvpvklR.png")
.tag("test")
.into(ivTest2)
Picasso.get().cancelTag("test")
複製程式碼
可以先tag標記下每個請求,然後可以批量處理。 分別是取消,暫停,恢復。
- setLoggingEnabled,isLoggingEnabled
public void setLoggingEnabled(boolean enabled) {
loggingEnabled = enabled;
}
public boolean isLoggingEnabled() {
return loggingEnabled;
}
複製程式碼
是否啟動日誌
- getSnapshot
@SuppressWarnings("UnusedDeclaration") public StatsSnapshot getSnapshot() {
return stats.createSnapshot();
}
複製程式碼
獲取到Picasso
的一個快照。
Picasso.get().snapshot.dump()
複製程式碼
然後直接列印。
===============BEGIN PICASSO STATS ===============
Memory Cache Stats
Max Cache Size: 57521883
Cache Size: 0
Cache % Full: 0
Cache Hits: 0
Cache Misses: 0
Network Stats
Download Count: 0
Total Download Size: 0
Average Download Size: 0
Bitmap Stats
Total Bitmaps Decoded: 0
Total Bitmap Size: 0
Total Transformed Bitmaps: 0
Total Transformed Bitmap Size: 0
Average Bitmap Size: 0
Average Transformed Bitmap Size: 0
===============END PICASSO STATS ===============
複製程式碼
這個就灰常的方便了,直接看當前Picasso的使用狀態
- invalidate
因為
Picasso
使用了LruCache
快取到記憶體中,key-value與url-bitmap對應起來(實際上不是儲存Bitmap,而是自己封裝了另外一個類,但是裡面是有Bitmap的,這裡先不具體)。invalidate可以移除快取。
public void invalidate(@Nullable Uri uri) {
if (uri != null) {
cache.clearKeyUri(uri.toString());
}
}
複製程式碼
- load 這個就不說了,上一篇文章介紹了很多了。
重要物件介紹
上面簡單的了Picasso物件,但是還有很多重要的物件。
我們可以從Picasso.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;
...
複製程式碼
這麼多可以配置的物件,ndicatorsEnabled,loggingEnabled,context先不說了。
我們來先來簡單介紹下另外幾個。
- Downloader downloader
預設實現
OkHttp3Downloader
@NonNull @Override public Response load(@NonNull Request request) throws IOException { return client.newCall(request).execute(); 複製程式碼
}
其實是可以自己複寫,使用自己的http框架 2. ExecutorService service 預設實現`PicassoExecutorService`
java
//建立了一個執行緒池,預設都是3個核心執行緒,然後還有一個有優先順序的阻塞佇列
PicassoExecutorService() {
super(DEFAULT_THREAD_COUNT, DEFAULT_THREAD_COUNT, 0, TimeUnit.MILLISECONDS,
new PriorityBlockingQueue<Runnable>(), new Utils.PicassoThreadFactory());
複製程式碼
} ``` 這裡其實還有一個比較有意思的方法
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:
setThreadCount(2);
break;
case TelephonyManager.NETWORK_TYPE_GPRS: // 2G
case TelephonyManager.NETWORK_TYPE_EDGE:
setThreadCount(1);
break;
default:
setThreadCount(DEFAULT_THREAD_COUNT);
}
break;
default:
setThreadCount(DEFAULT_THREAD_COUNT);
}
}
複製程式碼
就是會根據網路的情況使用不同的執行緒數。可以學習下。
也可以自定義
3. Cache cache
預設使用LruCache
public LruCache(@NonNull Context context) {
this(Utils.calculateMemoryCacheSize(context));
}
...
static int calculateMemoryCacheSize(Context context) {
ActivityManager am = getService(context, ACTIVITY_SERVICE);
boolean largeHeap = (context.getApplicationInfo().flags & FLAG_LARGE_HEAP) != 0;
int memoryClass = largeHeap ? am.getLargeMemoryClass() : am.getMemoryClass();
// Target ~15% of the available heap.
return (int) (1024L * 1024L * memoryClass / 7);
}
複製程式碼
這裡也很有意思,根據當前的app所能使用的記憶體值獲取一個比較合適的快取記憶體的最大值。自己可以複寫調整。
- Listener listener 沒有預設值
public interface Listener {
void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception);
}
複製程式碼
很顯然是用來全域性監聽圖片載入失敗的事件。 5. RequestTransformer transformer 預設
RequestTransformer IDENTITY = new RequestTransformer() {
@Override public Request transformRequest(Request request) {
return request;
}
};
複製程式碼
其實就是一個request的全域性的一個轉化。預設不轉化。 6. List requestHandlers 前面已經介紹過了預設有很多種requestHandlers,也可以自己定義 7. Bitmap.Config defaultBitmapConfig 預設為null 在requestHandler裡面的createBitmapOptions有使用到
static BitmapFactory.Options createBitmapOptions(Request data) {
final boolean justBounds = data.hasSize();
final boolean hasConfig = data.config != null;
BitmapFactory.Options options = null;
if (justBounds || hasConfig || data.purgeable) {
options = new BitmapFactory.Options();
options.inJustDecodeBounds = justBounds;
options.inInputShareable = data.purgeable;
options.inPurgeable = data.purgeable;
//在這裡,如果有config,就配置下,如果沒有那麼就預設
if (hasConfig) {
options.inPreferredConfig = data.config;
}
}
return options;
}
複製程式碼
一共這麼多選項,可以選擇。
總結
Picasso用起來也挺爽的,後面有空學習下Glide和Fresco做下對比