1. 程式人生 > >圖片載入框架 --Picasso 的基本使用

圖片載入框架 --Picasso 的基本使用

下面是我在學習Picasso過程中做的筆記,思路可能有些凌亂,如果閱讀過程中有發現不準確或者錯誤的地方歡迎交流

內容主要分三部分,第一部分是picasso的基本使用,第二部分是picasso的原始碼閱讀,最後一部分是關於原始碼中一些細節的梳理.

關於圖片載入庫的思考

我們為什麼要用圖片庫呢? 
圖片庫通常會對圖片載入邏輯進行封裝、優化,比如多級快取/非同步執行緒排程/圖片壓縮變換,有了這些特性,開發者不再需要關注記憶體佔用、 
OOM、網路請求等問題,而只需關注業務本身的邏輯,這對提高生產效率有很大幫助。

我工作半年以來也研究了一些主流的圖片庫,發現雖然每個圖片的架構和實現細節不太一樣,但是通常都會有以下模組:

  1. 請求分發模組。負責封裝請求,對請求進行優先順序排序,並按照型別進行分發。
  2. 快取模組。通常包括一個二級的快取,記憶體快取、磁碟快取。並預置多種快取策略。
  3. 下載模組。負責下載網路圖片。
  4. 監控模組。負責監控快取命中率、記憶體佔用、載入圖片平均耗時等。
  5. 圖片處理模組。負責對圖片進行壓縮、變換等處理。
  6. 本地資源載入模組。負責載入本地資源,如assert、drawable、sdcard等。
  7. 顯示模組。負責將圖片輸出顯示。

圖片載入庫

Android平臺圖片載入庫現狀

目前社群主流的圖片載入庫有Universal Image Loader,Picasso,Volley,Fresco,Glide.

Picasso簡介

A powerful image downloading and caching library for Android,developed by Square

Picasso的特性

  1. 絕對是最輕量的圖片載入庫,120kb.
  2. 自帶監控功能,可以檢測cache hit/記憶體大小等等資料
  3. 圖片預載入
  4. 執行緒併發數依網路狀態變化而變化、優先順序排程
  5. 圖片變換
  6. 圖片壓縮、自適應
  7. 易擴充套件

Picasso的使用

  • 載入一張網路圖片到ImageView
Picasso.with(context)
    .load(url)
    .placeholder
(R.drawable.user_placeholder) .error(R.drawable.user_placeholder_error) .into(imageView);//此種策略並不會壓縮圖片
  • 1
  • 2
  • 3
  • 4
  • 5
  • 預載入一張圖片
Picasso.with(this).load(URL).fetch();
Picasso.with(this).load(URL).fetch(Callback);
  • 1
  • 2

注意哦,如果你以以下面這種方式加上圖形變換preload的話:

Picasso.with(this).load(URL).rotate(20).fetch();
  • 1

再下面這種方式是取不到preload的圖片的,因為預快取的是經過變換後的圖片,它的cachekey會有rotation標識

Picasso.with(this).load(URL).into(imageView);
  • 1

當然我說的是preload到記憶體中的那份經過旋轉的圖片,http會快取旋轉前的圖片到磁碟(支援快取的情況下),所以最終還是可以從磁碟快取 
拿到圖片的。

  • 替換預設的Picasso
Picasso p = new Picasso.Builder(this).executor().downloader(downloader).memoryCache(cache).build();
Picasso.setSingletonInstance(p);
  • 1
  • 2
  • 同步call
 new AsyncTask<Void,Void,Bitmap>(){
        @Override
        protected Bitmap doInBackground(Void... params) {
            try {
                return Picasso.with(PicassoTestActivity.this).load(URL).get();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if(bitmap != null){
                imageView.setImageBitmap(bitmap);
            }
        }
    }.execute();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

注意,必須在非同步執行緒呼叫,否則crash,另外,這個結果並不會快取到記憶體裡面,所以慎用。

  • 自適應
Picasso.with(TestImageActivity.this).load(url).fit().into(imageview);
  • 1

fit方法的意思是,讓圖片的寬高恰好等於imageView的寬高.前提是你的imageView控制元件不能設定成wrap_content,也就是必須 
有大小才行。另外,如果使用了fit方法,那麼就不能呼叫resize.

  • 壓縮到指定尺寸
Picasso.with(TestImageActivity.this).load(url).resize(widthPixel,heightPixel).centerInside().into(imageView);
Picasso.with(TestImageActivity.this).load(URL).resizeDimen(R.dimen.width,R.dimen.height).centerCrop().into(iv);
  • 1
  • 2

resize後面通常接centerInside或者centerCrop。注意這跟ImageView的scaleTyoe沒有關係,僅僅指的是圖片的縮放方式。 
比如如下程式碼,iv不壓縮,iv_2寬高壓縮到40dp並且指定為centerInside.

<ImageView
        android:id="@+id/iv"
        android:background="#000"
        android:layout_width="100dp"
        android:layout_height="100dp"/>
<ImageView
    android:layout_below="@id/iv"
    android:id="@+id/iv_2"
    android:background="#000"
    android:layout_width="100dp"
    android:layout_height="100dp"/>

Picasso.with(TestImageActivity.this).load(URL).into(iv);
Picasso.with(TestImageActivity.this).load(URL).resizeDimen(R.dimen.width/*40dp*/, R.dimen.height/*40dp*/).centerInside().into(iv_2);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

最終顯示結果如下:

demo

可以很明顯看到下面的圖模糊許多,這是因為圖片被壓縮了,但是顯示的時候又被ImageView拉伸了(預設scaleType是fitCenter), 
要想不顯示拉伸的圖,可以給iv_2增加scaleType="centerInside",效果如下:

demo

  • 圖形變換
Picasso.with(TestImageActivity.this).load(URL).rotate(20).into(iv);
//自定義變換
 Picasso.with(TestImageActivity.this).load(URL).transform(new Transformation() {
                    @Override
                    public Bitmap transform(Bitmap source) {//從原圖中間裁剪一個正方形
                        int size = Math.min(source.getWidth(), source.getHeight());
                        int x = (source.getWidth() - size) / 2;
                        int y = (source.getHeight() - size) / 2;
                        Bitmap result = Bitmap.createBitmap(source, x, y, size, size);
                        if (result != source) {
                            source.recycle();
                        }
                        return result;
                    }

                    @Override
                    public String key() {
                        return "square()";
                    }
                }).into(iv);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 暫停/重啟請求任務

通常在滑動列表的時候需要暫停請求


Picasso.with(context).load(URL).tag(context);


public class SampleScrollListener implements AbsListView.OnScrollListener {
  private final Context context;


  public SampleScrollListener(Context context) {
    this.context = context;
  } 


  @Override 
  public void onScrollStateChanged(AbsListView view, int scrollState) {
    final Picasso picasso = Picasso.with(context);
    if (scrollState == SCROLL_STATE_IDLE || scrollState == SCROLL_STATE_TOUCH_SCROLL) {
      picasso.resumeTag(context);
    } else { 
      picasso.pauseTag(context);
    } 
  } 


  @Override 
  public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                       int totalItemCount) {
    // Do nothing. 
  } 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

Picasso原始碼分析

其實看原始碼分析什麼的最無聊了,最好的方式是自己跟一遍原始碼,picasso裡面有很多設計很優雅的地方,只有自己看了才會真正有收穫.

整體架構

整體架構

Picasso中的核心類包括PicassoDispatcherBitmapHunterRequestHandlerRequestActionCache 
等.Picasso類是一個負責圖片下載、變換、快取的管理器,當它收到一個圖片下載請求的時候,它會建立Request並提交給Dispatcher
Dispatcher會尋找對應的處理器RequestHandler,並將請求與該處理器一起提交給執行緒池執行,圖片獲取成功後,最終會交給 
PicassoDrawable顯示到Target上。

它將一張圖片的載入過程分為八步,依次為:

建立->入隊->執行->解碼->變換->批處理->完成->分發->顯示(可選)

也可以從日誌中看到這個過程:

11-05 10:39:00.942 2952-2952/com.taobao.paimainews D/Picasso: Main        created      [R0] Request{http://ww3.sinaimg.cn/mw600/006g34NHgw1exj5c4hmfvj30hs0qoqff.jpg resize(90,300) centerInside rotation(30.0) ARGB_8888}
11-05 10:39:00.981 2952-3109/com.taobao.paimainews D/Picasso: Dispatcher  enqueued     [R0]+40ms
11-05 10:39:00.993 2952-3193/com.taobao.paimainews D/Picasso: Hunter      executing    [R0]+50ms
11-05 10:39:01.038 2952-3193/com.taobao.paimainews D/Picasso: Hunter      decoded      [R0]+97ms
11-05 10:39:01.041 2952-3193/com.taobao.paimainews D/Picasso: Hunter      transformed  [R0]+100ms
11-05 10:39:01.042 2952-3109/com.taobao.paimainews D/Picasso: Dispatcher  batched      [R0]+101ms for completion
11-05 10:39:01.279 2952-2952/com.taobao.paimainews D/Picasso: Main        completed    [R0]+338ms from DISK
11-05 10:39:01.280 2952-3109/com.taobao.paimainews D/Picasso: Dispatcher  delivered    [R0]+338ms
  • 1
  • 2
  • 3
  • 相關推薦

    Android 圖片載入框架Picasso基本使用和原始碼完全解析

    寫在之前 原本打算是每週更新一篇博文,同時記錄一週的生活狀態,但是稍微工作忙一點就顧不上寫部落格了。悲催 還是說下最近的狀況,最近兩週一直在接公司申請的計費點, 沃商店,銀貝殼,微信等等,然後就是不停的被人催促催促,真是一個頭兩個大。在這期間專案組還搞了個A

    圖片載入框架 --Picasso基本使用

    下面是我在學習Picasso過程中做的筆記,思路可能有些凌亂,如果閱讀過程中有發現不準確或者錯誤的地方歡迎交流 內容主要分三部分,第一部分是picasso的基本使用,第二部分是picasso的原始碼閱讀,最後一部分是關於原始碼中一些細節的梳理. 關於圖片載

    Android圖片載入框架Picasso最全使用教程 一

    Picasso介紹 Picasso是Square公司開源的一個Android圖形快取庫 A powerful image downloading and caching library for Android 一個Android下強大的圖片下載快

    安卓網路圖片載入框架-Picasso使用教程

    Picasso介紹 Picasso是Square公司開源的一個Android圖形快取庫 A powerful image downloading and caching library for Android  一個Android下強大的圖片下載快取庫 Picass

    Android中圖片載入框架Picasso的使用

    技術要點 基本顯示(非同步載入,圖片壓縮,圖片快取) 載入中和載入錯誤的圖片顯示 設定圖片尺寸(Resize)、縮放(Scale)和裁剪(Crop) 圖片旋轉 設定轉換器 取消預設的記憶體快取 設定快取指示器 請求優先順序設定 圖片還未加載出來時取消

    Android之圖片載入框架Picasso原始碼解析

    個人開發的微信小程式,目前功能是書籍推薦,後續會完善一些新功能,希望大家多多支援! 前言 picasso是Square公司開源的一個Android圖形快取庫,地址http://square.github.io/picasso/,可以實現圖片下載和快取功能。僅

    圖片載入框架Picasso的使用

    1.介紹 Picasso是由Square公司開發的一個圖片載入框架 2.使用 如果你是用的是Android Studio,你只需要在dependency section中的build.gradle中新增 compile'com.squareup.picasso:pica

    Android圖片載入框架——Picasso和Glide

           首先說Picasso,Picasso 是 Square 公司的傑作,名字叫「畢加索,充滿文藝氣息,意為載入圖片就像畫畫一樣,是一門藝術。Picasso 不僅具備載入圖片的強大功能,還是如此的簡潔。 Picasso預設的快取分配大小特點:   LRU快取佔應用程

    Android圖片載入框架Picasso使用教程 (三)

    前面我們對Picasso的用法有了一定得了解,下面就分析一下一些特殊情況下,Picasso的用法. 呼叫.noFade()   Picasso的預設圖片載入方式有一個淡入的效果,如果呼叫了noFade(),載入的圖片將直接顯示在ImageView上 <font

    強大的圖片載入框架Picasso和Glide

    一、Picasso Picasso是Square公司出品的一個強大的圖片下載和快取圖片庫。官方網址是:http://square.github.io/picasso/ 只需要一句程式碼就可以將圖片下載並設定到ImageView上。 特點:    1.在adapter中需

    圖片載入框架Picasso和Glide比較

    A full-stack developer with more than 6 years experience on Android Application Development and more than 12 years in Mobile Application Development indust

    Android圖片載入框架Picasso最全使用教程

    Picasso介紹 A powerful image downloading and caching library for Android 一個Android下強大的圖片下載快取庫 Picasso實現了圖片的非同步載入,並解決了Android中載入圖片時常見的一些問題,它有以下特點: 在Adap

    Android圖片載入框架Picasso使用教程 (四)

    通過前幾篇的學習,我們已經對Picasso的載入圖片的用法有了很深的瞭解,接下來我們開始分析Picasso為我們提供的其他高階功能及記憶體分析,Let’s Go ! (ps:想要獲取更多學習資料可加qq1692250804!)      Picasso進行圖片的旋轉(Ro

    Picasso圖片載入框架的使用

    Picasso圖片載入框架的使用 Android 中有幾個比較有名的圖片載入框架,Universal ImageLoader、Picasso、Glide和Fresco。它們各有優點,以前一直用的是ImageLoader 做專案中的圖片載入,由於作者宣佈ImageLoader 不會在更新了,因

    Android圖片載入框架最全解析(一),Glide的基本用法

    現在Android上的圖片載入框架非常成熟,從最早的老牌圖片載入框架UniversalImageLoader,到後來Google推出的Volley,再到後來的新興軍Glide和Picasso,當然還有Facebook的Fresco。每一個都非常穩定,功能也都十分強大。但是它們

    Android圖片載入框架最全解析(一)Glide的基本用法

    現在Android上的圖片載入框架非常成熟,從最早的老牌圖片載入框架UniversalImageLoader,到後來Google推出的Volley,再到後來的新興軍Glide和Picasso,當然還有Facebook的Fresco。每一個都非常穩定,功能也都

    Android 圖片載入框架 Volley框架原始碼 以及Picasso和Glide比較

    首先了解一下,它是封裝了HTTPConnection和HTTPClient類的一個框架, 適用於資料量少但是通訊頻繁的情況,如載入圖片; 就拿StringRequest(用來請求字串的)舉例: Volley的順序是 :  Http請求-------再接受響應   只

    常用圖片載入框架比較(Glide、volley、Picasso

                 Volley                      一、ImageRequest:                                    來對網路圖片進行請

    Android 三大圖片載入框架的對比——ImageLoader,Picasso,Glide

    一、ImageLaoder介紹    << Universal ImageLoader 是很早開源的圖片快取,在早期被很多應用使用多執行緒下載圖片,圖片可以來源於網路,檔案系統,專案資料夾assets中以及drawable中等支援隨意的配置ImageLoader,

    圖片載入框架的選擇問題(Fresco,Glide,Picasso,UIL)

    確實這四個都非常強大,且大部分帖子文件都對這些框架有很深入的介紹。所以今天來講一點不一樣的。 首先,說說需求。需求有兩點,一是列表icon。二是點選列表進入詳情後展示詳情圖片,如下圖: 看樣子是很簡單的需求,但是做到後期還是會有問題的。 1.ImageLoader: