Android 常用開源框架源碼解析 系列 (十一)picasso 圖片框架
阿新 • • 發佈:2018-08-13
hand 需求 trim cor pan setname github ESS true 一、前言
Picasso 強大的圖片加載緩存框架
api加載方式和Glide 類似,均是通過鏈式調用的方式進行調用
1.1、作用
Picasso 管理整個圖片加載、轉換、緩存等策略
1.2、簡單調用:
Picasso .with(this 傳入一個單例,上下文).load(“url”/file文件/資源路徑) .into()
1.2.1 、一些簡單的鏈式調用參數
.placeholder(R.drawable.xx) //網絡未加載完成的時候顯示的本地資源圖片
.error(R.drawable.xx) //網絡加載失敗顯示的本地資源圖片
.resize(480,800) //手動控制圖片寬高 ,對整個屏幕圖片進行設置像素設置
.centerCrop () //造成圖片拉伸扭曲的時候,將整個圖片充滿ImageView邊界,進行居中裁剪邊界
.rotate( 度數 0.0坐標開始轉 ) //旋轉動畫效果
.priority() //請求優先級,會影響請求執行順序,但不是百分之百保證的,只會往高優先級靠攏
.tag(“xxxx”) //允許為每一個請求設置一個tag
ps:如果不設置tag,在list列表請求的時候,會加載所有的圖片請求,就會造成Ui卡頓;
而有了tag ,listView就可以進行監聽而後進行不同的操作事件
可以在滑動的setOnScrollListener()的監聽事件中 :
在onScrollStateChanged()方法中通過判斷是否處於IDLE狀態,
如果處於IDLE狀態就恢復 tag(picasso.resumeTag) 繼續加載;
如果是在滑動狀態,停止圖片加載的請求 picasso.pauseTag
picasson的內存緩存 和 磁盤緩存 默認都會開啟的 ;但是不需要總是開啟,如果加載大圖片再緩存一份就很容易造成OOM
.memoryPolicy(MemoryPolicy.No_CACHE) //picasso 的內存緩存模式
.networkPolicy(MemoryPolicy.No_CACHE) //人為禁掉 磁盤緩存
二、Picasso 源碼
2.1、 引入
implementation ‘com.squareup.picasso:picasso:2.71828‘
or Maven:
<dependency>
<groupId>com.squareup.picasso</groupId>
<artifactId>picasso</artifactId>
<version>2.71828</version>
</dependency>
2.2 代碼混淆
If you are using ProGuard you might need to add OkHttp‘s rules: https://github.com/square/okhttp/#proguard
2.3 源碼分析
// 2.3.1 with()函數的進入-基礎配置工作,dispatch分發器配置,picasso對象配置
返回一個picasso對象的實例主旨功能 ,Picasso 入口函數
public void picasso() {
Picasso.with(this) //使用單例模式構建保證在使用的時候整個module只有一個picasso存在
.load("url")
.into(imageView);
}
with()://通過雙重鎖機制 保護線程的安全,通過Builder內部類的build()方法創建 Picasso對象
public static Picasso with (Context context) {
if (singleton == null) {
synchronized (Picasso.class) {
if (singleton == null) {
singleton = new Builder(context).build();
}
}
}
return singleton;
}
build():
public Picasso build() {
Context context = this.context;
//實際圖片加載的過程
if (downloader == null) {
downloader = Utils.createDefaultDownloader(context);
——————————————————
ps: 通過反射查找是否有OkHttpClient庫,如果有就通過OkHttp庫 進行圖片下載和加載方式
Class.forName("com.squareup.okhttp.OkHttpClient");
return OkHttpLoaderCreator.create(context);
}else {
//若沒有OkHttp庫就通過HttpURLConnection進行實現
return new UrlConnectionDownloader(context);
}
——————————————————
//通過LruCache 最近使用內存算法;進行內存緩存 策略,picasso 中指定了手機的內存為15%
——————————————————
ps:LruCache 實現了Lru算法復習;最近使用最少的緩存會被刪除;其實現會通過LinkedHashMap進行,每次調用get()、put()會將對象放到鏈表的尾端,每次put依然會將對象放到鏈表的尾部。當內存緩存達到最大值的時候,他就會將我們的鏈表頭部的對象移除,以達到Lru算法的目的。
——————————————————
if (cache == null) {
cache = new LruCache(context);
}
//picasso 的線程池Executor
if (service == null) {
service = new PicassoExecutorService();
——————————————————
ps:PicassoExecutorService 繼承自 ThreadPoolExecutor
private static final int DEFAULT_THREAD_COUNT = 3;
public ThreadPoolExecutor(int corePoolSize, //核心線程數量,如果沒有任務的話,整個核心的corePoolSize也不會終止,除非認為設置需要核心線程
int maximumPoolSize, //線程池中允許的最大的線程數量,線程池數量越大,開銷越大
long keepAliveTime, //當我們線程池中的線程線程數目比核心線程多的時候,如果超過了keepAliveTime這個時間,那麽多余的線程就會被回收,也就是被移出線程池
TimeUnit unit,
BlockingQueue<Runnable> workQueue, //阻塞隊列,是一個線程安全隊列
ThreadFactory threadFactory, //用來構造線程池的工廠
RejectedExecutionHandler handler) //任務阻塞的時候線程池的一種處理方式
{
- 當有新任務的時候先觀察corePoolSize值
- 然後觀察workQueue工作隊列是否已經滿了
- 最好判斷是否有小於線程池的最大值
- 1、如果線程池中線程的數目少於corePoolSize; 這時候線程池會重新創建一個核心線程的,直到核心線程數量達到corePoolSize就不會再創建新核心線程了
- 2、如果線程池中線程的數目大於或是等於corePoolSize,但是工作隊列workQueue沒有滿,那麽新的任務依然會放置到這個隊列當中,按照先進先出的原則來進行執行
- 3、如果線程池中的線程數目大於等於corePoolSize,並且工作隊列workQueue滿了,但是總線程數目小於maximumPoolSize,那麽可以直接創建一個線程,處理並添加到任務當中
- 4、如果工作隊列滿了,並且線程池中線程的數目到達了最大數目maximumPoolSize的時候,這時候就需要用到RejectedExecutionHandler這個對象進行處理,默認處理方式是丟棄任務並拋出異常
Android 常用開源框架源碼解析 系列 (十一)picasso 圖片框架