android開源項目:圖片下載緩存庫picasso


picasso是Square公司開源的一個Android圖形緩存庫,地址http://square.github.io/picasso/,可以實現圖片下載和緩存功能。

picasso有如下特性:

  • 在adapter中回收和取消當前的下載;
  • 使用最少的內存完成復雜的圖形轉換操作;
  • 自動的內存和硬盤緩存;
  • 圖形轉換操作,如變換大小,旋轉等,提供了接口來讓用戶可以自定義轉換操作;
  • 加載載網絡或本地資源;
  • 可以轉換為自己需要的request(Square公司開源的另一個網絡支持庫:retrofit支持轉化json,protocol buffers).

1.picasso的簡單使用

1 Picasso.with(context).load(url).placeholder(R.drawable.pic).error(R.drawable.pic).into(tagert);
需要注意:url為http鏈接時,load(url),當url為本地圖片路徑時load(new File(url)).

需要對圖片簡單處理:transform(Transformation);
如下是顯示圓形圖片
 
//重載函數
public Bitmap transform(Bitmap source) { int width = source.getWidth(); int height = source.getHeight(); int x = 0, y = 0; if (mSquareRound && width != height) { if (width < height) { y = (height - width)/2; } else { x = (width - height)/2; } width = height = Math.min(width, height); Bitmap tempSource = Bitmap.createBitmap(source, x, y, width, height); source.recycle(); source = tempSource; } Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Paint paint = new Paint(); paint.setDither(true); paint.setAntiAlias(true); BitmapShader shader = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); paint.setShader(shader); Canvas canvas = new Canvas(output); final RectF bounds = new RectF(0, 0, width, height); canvas.drawOval(bounds, paint); source.recycle(); return output; }

transform(new RoundTransformation(true));

 

2.picasso的類圖如下:

關鍵類的簡單介紹:

Cache:緩存類,子類LruCache才采用Least Recently Used 近期最少使用算法,當然LinkedHashMap已實現這個策略,只需根據配置的緩存大小來trimToSize。

picass緩存策略單一,沒有另一個圖片下載緩存庫 Android-universal-Image-Loader 緩存策略豐富:FIFOLimitedMemoryCache ,LimitedAgeMemoryCache 等

而本地文件緩存,picasso引用okhttp的文件緩存,而Android-universal-Image-Loader也不同幾種文件緩存策略。

 

RequestCreator:Requst構建者,可以通過不同參數配置request請求。

Request:請求封裝類,之后把所有對圖形的操作都會記錄在這里,供之后圖形的創建使用,如重新計算大小,旋轉角度,也可以自定義變換,只需要實現Transformation,一個bitmap轉換的接口。傳到另一個結構中Action。

Action:Action代表了一個具體的加載任務,主要用於圖片加載后的結果回調,有兩個抽象方法,complete和error.來通知上層。

BitmapHunter:一個runnable線程,網絡下載工作線程,交給ExecutorServer管理執行。

Downloader:網絡圖片下載器,子類不同來選擇http client。

RequestHandler:請求處理類,子類根據圖片來源獲取資源。

Dispathcer:任務調度器,調度和維護者actions 和 bitmapHunter,當bitmaphunter獲取到圖片時,會轉給dispather,發送異步消息,最終會轉到action.complete()或者action.error().

 

3.picasso.with(context).loar(http).into(imageview);流程圖如下

 

網上找到一個一張很好的picasso流程分析圖:http://www.happyhls.me/blog/2014/11/27/picasso%E6%BA%90%E4%BB%A3%E7%A0%81%E5%88%86%E6%9E%90%EF%BC%9A5%E3%80%81picasso%E6%9E%B6%E6%9E%84%E5%88%86%E6%9E%90/

 要點:

1在into(target).中做了是否在UI主線成操作,由於要顯示默認的圖片,得保證在主線程中對ui操作。

2.Dispather本質上可以看成一個線程,action提交和請求結果的回調都是在DispatcherThread線程中通過DispacherHandler處理。

3.picasso中通過廣播監控網絡狀態,來動態改變PicassoExecutorService中線程數量。

4.picasso單例的思考:picasso構建時,初始化了cache,注冊了監聽網絡狀態的廣播等,在調用shutDown()方法中做了cache清空和注銷廣播工作,但是,對於這個全局picasso在什么時機做清理工作了(顯式調用shutdown()),這個時機不好把握,除非app能夠自身監聽application被關閉,回調shutdown.如果不顯式調用shutdown,cache沒有清空,廣播就沒有注銷。對於context.registerReceiver(),context可能是application,可能是activity(在ams,在activity被destory過程會隱式調用unregisterReceiver()或unbindService()),對於context是application沒有隱式注銷unregisterReceiver(),可能存在潛在問題(內存泄露會不會出現了);如果想對每個activity擁有個picasso,則可以使用

Picasso.Builder(context).build();這樣可以在每個activity中ondestory中顯式調用picasso.shutdown();

5.BitmapHunt.hunt()中,,同一時刻,僅允許一張圖片進行解碼,加了同步安全,進行Transformation,防止oom.

 

4.使用picasso可能出現的問題:

1.圖片有時會顯示不了,查看應用中圖片緩存文件,對一張圖片,會生成兩個文件:,.0文件保存了http響應相應的信息,.1文件時加密后的圖片文件。.0文件的內容如下:

http://192.168.2.40:82/group1/M00/0A/60/wKgCKFQJQkKABEn9AAPhsEdiW-o.phpzqf
GET
0
HTTP/1.1 200 OK
9
Server: nginx/1.2.6
Date: Tue, 16 Sep 2014 12:02:26 GMT
Content-Length: 254384
Last-Modified: Fri, 05 Sep 2014 04:55:30 GMT
Connection: keep-alive
Accept-Ranges: bytes
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1410868547182
OkHttp-Received-Millis: 1410868547357

這邊出現問題時,Content-Length: 0,但是圖片確實存在。如果出現有時顯示不了,可以從這方面查看下。可行的方法:

定制Downloader,配置緩存目錄和緩存大小。

2.當picasso顯示列表中大量圖片時,查看大圖時,有時還是會出現oom,除了對長寬比壓縮,也可以以另外一個進程查看大圖。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM