編輯:關於android開發
圖片加載涉及到圖片的緩存、圖片的處理、圖片的顯示等。而隨著市面上手機設備的硬件水平飛速發展,對圖片的顯示要求越來越高,稍微處理不好就會造成內存溢出等問題。很多軟件廠家的通用做法就是借用第三方的框架進行圖片加載。 開源框架的源碼還是挺復雜的,但使用較為簡單。大部分框架其實都差不多,配置稍微麻煩點,但是使用時一般只需要一行,顯示方法一般會提供多個重載方法,支持不同需要。這樣會減少很不必要的麻煩。同時,第三方框架的使用較為方便,這大大的減少了工作量、提高了開發效率。本文主要介紹四種常用的圖片加載框架,分別是Fresco、ImageLoader、 Picasso、 Glide,包括他們各自的優缺點、使用步驟等等。
首先看 Fresco, Fresco 是 Facebook 推出的開源圖片緩存工具,主要特點包括:兩個內存緩存加上 Native 緩存構成了三級緩存,支持流式,可以類似網頁上模糊漸進式顯示圖片,對多幀動畫圖片支持更好,如 Gif、WebP。它的優點是其他幾個框架沒有的, 或者說是其他幾個框架的短板。
優點:
1. 圖片存儲在安卓系統的匿名共享內存, 而不是虛擬機的堆內存中, 圖片的中間緩沖數據也存放在本地堆內存, 所以, 應用程序有更多的內存使用, 不會因為圖片加載而導致oom, 同時也減少垃圾回收器頻繁調用回收 Bitmap 導致的界面卡頓, 性能更高。
2. 漸進式加載 JPEG 圖片, 支持圖片從模糊到清晰加載。
3. 圖片可以以任意的中心點顯示在 ImageView, 而不僅僅是圖片的中心。
4. JPEG 圖片改變大小也是在 native 進行的, 不是在虛擬機的堆內存, 同樣減少 OOM。
5. 很好的支持 GIF 圖片的顯示。
缺點:
1. 框架較大, 影響 Apk 體積
2. 使用較繁瑣
使用步驟:
1. 引入 Fresco,包括兩種方式,在線和離線。
在線引入依賴腳本形式,在dependencies中添加依賴,
compile 'com.facebook.fresco:fresco:0.9.0'
引入離線引入,需要導入的arr包較多,包括:
compile(name: 'drawee-0.9.0', ext: 'aar') compile(name: 'fbcore-0.9.0', ext: 'aar') compile(name: 'imagepipeline-0.9.0', ext: 'aar') compile(name: 'imagepipeline-base-0.9.0', ext: 'aar') compile files('libs/bolts-android-1.1.4.jar')
上面提到的aar其實就是lib module壓縮包的形式,包括.class和相關的資源文件,平常使用的jar僅僅包括.class文件。使用aar包時,還需要來到project `build.gradle`裡面, 在allprojects方法體加入
allprojects { repositories { jcenter() //add begin flatDir { dirs 'libs' } //add end }
2. 需要在程序入口方法裡面進行初始化。在oncreate方法中添加初始化語句。
Fresco.initialize(context);
3. 在布局文件中,需要使用圖片展示地方,使用它定義的控件
<com.facebook.drawee.view.SimpleDraweeView android:id="@+id/iv_img" android:layout_width="150dp" android:layout_height="150dp" android:src="@mipmap/ic_launcher" fresco:fadeDuration="300" fresco:roundingBorderColor="#ccc" fresco:roundingBorderWidth="2dp"/>
4.設置靜態圖片,在代碼中具體寫如下代碼
// 圖片加載 Uri uri = Uri.parse(data.url); holder.ivIcon.setImageURI(uri);
5. 設置gif圖片,在代碼中具體寫如下代碼
DraweeController gifController = Fresco.newDraweeControllerBuilder().setUri(uri) .setAutoPlayAnimations(true).build(); holder.ivIcon.setController(gifController);
ImageLoader是比較老的框架,是github社區上star最多的一個項目,可以理解為點贊最多滴,應該是最有名的一個國內很多知名軟件都用它包括淘寶京東聚劃算等等。整個庫分為 ImageLoaderEngine,Cache 及 ImageDownloader,ImageDecoder,BitmapDisplayer,BitmapProcessor 五大模塊,其中 Cache 分為 MemoryCache 和 DiskCache 兩部分。簡單的講就是 ImageLoader 收到加載及顯示圖片的任務,並將它交給 ImageLoaderEngine,ImageLoaderEngine 分發任務到具體線程池去執行,任務通過 Cache 及 ImageDownloader 獲取圖片,中間可能經過 BitmapProcessor 和 ImageDecoder 處理,最終轉換為Bitmap 交給 BitmapDisplayer 在 ImageAware中顯示。特點是穩定, 加載速度適中, 缺點在於不支持GIF圖片加載, 使用稍微繁瑣, 並且緩存機制沒有和 http 的緩存很好的結合, 完全是自己的一套緩存機制。使用比較簡單,這個框架的github主頁上也有快速使用的步驟,基本上就是在application類裡的oncreate方法(整個程序開始時運行一次)中進行一下簡單的基本配置,可以根據需要自行進行設定,懶得設定的話框架也提供了一個默認的配置,調用一個方法即可。基本上是配置一些類似於:緩存類型啊,緩存上限值啊,加載圖片的線程池數量啊等等。此外在頁面內顯示的時候還要設置一個顯示配置這個配置不同於基本配置,一個項目裡可以根據需要創建多個配置對象使用,這個配置就比較具體了,可以設置是否使用disk緩存(存到sd卡裡一般),加載圖片失敗時顯示的圖片,默認圖片,圖片的色彩樣式等。ImageLoader和Volley圖片部分還包括其他大部分圖片框架,基本上圖片處理都差不多,區別僅在於部分優化了,而優化方面UIL即Universal-Image-Loader框架做的最好,配置好以後,就是簡單的使用了,創建一個圖片加載對象,然後一行代碼搞定顯示圖片功能。參數一般是入你需要顯示的圖片url和imageview對象。
優點:
1.支持下載進度監聽
2.可以在 View 滾動中暫停圖片加載,通過 PauseOnScrollListener 接口可以在 View 滾動中暫停圖片加載。
3.默認實現多種內存緩存算法 這幾個圖片緩存都可以配置緩存算法,不過 ImageLoader 默認實現了較多緩存算法,如 Size 最大先刪除、使用最少先刪除、最近最少使用、先進先刪除、時間最長先刪除等。
4.支持本地緩存文件名規則定義
使用步驟:
1. 在Application子類中的onCreate方法中初始化ImageLoaderConfiguration
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)// .threadPriority(Thread.NORM_PRIORITY - 2)// .denyCacheImageMultipleSizesInMemory()// .diskCacheFileNameGenerator(new Md5FileNameGenerator())// .diskCacheSize(50 * 1024 * 1024) // 50 Mb .memoryCache(new LruMemoryCache(4 * 1024 * 1024)).tasksProcessingOrder(QueueProcessingType.LIFO)// .writeDebugLogs() // Remove for release app .build(); // Initialize ImageLoader with configuration. ImageLoader.getInstance().init(config);
2. 在具體的地方直接
//圖片加載 // ImageLoader.getInstance().displayImage(data.url, holder.ivIcon); DisplayImageOptions option = new DisplayImageOptions.Builder() .resetViewBeforeLoading(true) .cacheOnDisk(true) .imageScaleType(ImageScaleType.EXACTLY) .bitmapConfig(Bitmap.Config.RGB_565) .considerExifParams(true) .displayer(new FadeInBitmapDisplayer(300)) .build(); ImageLoader.getInstance().displayImage(data.url, holder.ivIcon, option);
3. 加載各種格式圖片
String imageUri = "http://site.com/image.png"; // 網絡圖片 String imageUri = "file:///mnt/sdcard/image.png"; //SD卡圖片 String imageUri = "content://media/external/audio/albumart/13"; // 媒體文件夾 String imageUri = "assets://image.png"; // assets String imageUri = "drawable://" + R.drawable.image; // drawable文件
4. 提供了豐富的緩存策略
內存緩存,現在我們來看Universal-Image-Loader有哪些內存緩存策略
1. 只使用的是強引用緩存
LruMemoryCache(這個類就是這個開源框架默認的內存緩存類,緩存的是bitmap的強引用,下面我會從源碼上面分析這個類)
2.使用強引用和弱引用相結合的緩存有
UsingFreqLimitedMemoryCache(如果緩存的圖片總量超過限定值,先刪除使用頻率最小的bitmap)
LRULimitedMemoryCache(這個也是使用的lru算法,和LruMemoryCache不同的是,他緩存的是bitmap的弱引用)
FIFOLimitedMemoryCache(先進先出的緩存策略,當超過設定值,先刪除最先加入緩存的bitmap)
LargestLimitedMemoryCache(當超過緩存限定值,先刪除最大的bitmap對象)
LimitedAgeMemoryCache(當 bitmap加入緩存中的時間超過我們設定的值,將其刪除)
3.只使用弱引用緩存
WeakMemoryCache(這個類緩存bitmap的總大小沒有限制,唯一不足的地方就是不穩定,緩存的圖片容易被回收硬盤緩存)
FileCountLimitedDiscCache(可以設定緩存圖片的個數,當超過設定值,刪除掉最先加入到硬盤的文件)
LimitedAgeDiscCache(設定文件存活的最長時間,當超過這個值,就刪除該文件)
TotalSizeLimitedDiscCache(設定緩存bitmap的最大值,當超過這個值,刪除最先加入到硬盤的文件)
UnlimitedDiscCache(這個緩存類沒有任何的限制)
Picasso 是 Square 開源的項目,且他的主導者是 JakeWharton,所以廣為人知。square公司,很多知名的開源也是該公司`android-times-square,leakcanary,okhttp,retrofit`。 Picasso的使用方便, 一行代碼完成加載圖片並顯示, 框架體積小。但是不支持 GIF, 並且它可能是想讓服務器去處理圖片的縮放, 它緩存的圖片是未縮放的, 並且默認使用 ARGB_8888 格式緩存圖片, 緩存體積大。整個庫分為 Dispatcher,RequestHandler 及 Downloader,PicassoDrawable 等模塊。Dispatcher 負責分發和處理 Action,包括提交、暫停、繼續、取消、網絡狀態變化、重試等等。簡單的講就是 Picasso 收到加載及顯示圖片的任務,創建 Request 並將它交給 Dispatcher,Dispatcher 分發任務到具體 RequestHandler,任務通過 MemoryCache 及 Handler(數據獲取接口) 獲取圖片,圖片獲取成功後通過 PicassoDrawable 顯示到 Target 中。需要注意的是上面 Data 的 File system 部分,Picasso 沒有自定義本地緩存的接口,默認使用 http 的本地緩存,API 9 以上使用 okhttp,以下使用 Urlconnection,所以如果需要自定義本地緩存就需要重定義 Downloader。
Picasso 優點
1.自帶統計監控功能。支持圖片緩存使用的監控,包括緩存命中率、已使用內存大小、節省的流量等。
2.支持優先級處理。每次任務調度前會選擇優先級高的任務,比如 App 頁面中 Banner 的優先級高於 Icon 時就很適用。
3.支持延遲到圖片尺寸計算完成加載
4.支持飛行模式、並發線程數根據網絡類型而變。 手機切換到飛行模式或網絡類型變換時會自動調整線程池最大並發數,比如 wifi 最大並發為 4,4g 為 3,3g 為 2。 這裡 Picasso 根據網絡類型來決定最大並發數,而不是 CPU 核數。
5.“無”本地緩存。無”本地緩存,不是說沒有本地緩存,而是 Picasso 自己沒有實現,交給了 Square 的另外一個網絡庫 okhttp 去實現,這樣的好處是可以通過請求 Response Header 中的 Cache-Control 及 Expired 控制圖片的過期時間。
使用步驟:
1. 導入Picasso的jar包,添加依賴
2. 加載圖片
//圖片加載 Picasso.with(mContext) //創建Picasso .load(data.url) //傳入路徑 .fade(300) //淡化效果時長 .into(holder.ivIcon); //圖片加載到那個位置
Glide可以說是 Picasso 的升級版, 有 Picasso 的優點, 並且支持 GIF 圖片加載顯示, 圖片緩存也會自動縮放, 默認使用 RGB_565 格式緩存圖片, 是 Picasso 緩存體積的一半。谷歌為我們介紹了一個名叫 Glide 的圖片加載庫,作者是`bumptech`。這個庫被廣泛的運用在google的開源項目中,包括2014年google I/O大會上發布的官方app。整個庫分為 RequestManager(請求管理器),Engine(數據獲取引擎)、 Fetcher(數據獲取器)、MemoryCache(內存緩存)、DiskLRUCache、Transformation(圖片處理)、Encoder(本地緩存存儲)、Registry(圖片類型及解析器配置)、Target(目標) 等模塊。
簡單的講就是 Glide 收到加載及顯示資源的任務,創建 Request 並將它交給RequestManager,Request 啟動 Engine 去數據源獲取資源(通過 Fetcher ),獲取到後 Transformation 處理後交給 Target。Glide 依賴於 DiskLRUCache、GifDecoder 等開源庫去完成本地緩存和 Gif 圖片解碼工作。
Glide 優點
1.不僅僅可以進行圖片緩存還可以緩存媒體文件。Glide 不僅是一個圖片緩存,它支持 Gif、WebP、縮略圖。甚至是 Video,所以更該當做一個媒體緩存。
2.支持優先級處理。
3.與 Activity/Fragment 生命周期一致,支持 trimMemory。Glide 對每個 context 都保持一個 RequestManager,通過 FragmentTransaction 保持與 Activity/Fragment 生命周期一致,並且有對應的 trimMemory 接口實現可供調用。
4.支持 okhttp、Volley。Glide 默認通過 UrlConnection 獲取數據,可以配合 okhttp 或是 Volley 使用。實際 ImageLoader、Picasso 也都支持 okhttp、Volley。
5.內存友好。Glide 的內存緩存有個 active 的設計,從內存緩存中取數據時,不像一般的實現用 get,而是用 remove,再將這個緩存數據放到一個 value 為軟引用的 activeResources map 中,並計數引用數,在圖片加載完成後進行判斷,如果引用計數為空則回收掉。內存緩存更小圖片,Glide 以 url、view_width、view_height、屏幕的分辨率等做為聯合 key,將處理後的圖片緩存在內存緩存中,而不是原始圖片以節省大小與 Activity/Fragment 生命周期一致,支持 trimMemory。
圖片默認使用默認 RGB_565 而不是 ARGB_888,雖然清晰度差些,但圖片更小,也可配置到 ARGB_888。
6.Glide 可以通過 signature 或不使用本地緩存支持 url 過期
使用步驟
1. 導入Glide的jar包,添加依賴
2. 加載圖片
Glide.with(mContext) //創建Glide .load(data.url) //傳入路徑 .into(holder.ivIcon);//圖片加載到那個位置
Android群英傳筆記系列一view的介紹,android群英 學習完第一行代碼後,繼續學習Android群英傳,希望能堅持下去,好好學習完這本書,並及時做好相關筆記
Android Studio中的EditText控件使用詳解 一:新建HelloEditText工程 創建設置如下: Project name:HelloEditTe
android 特殊用戶通知用法匯總--Notification源碼分析 一直用的android手機,用過這麼多的app,平時也會遇到有趣的通知提醒,在這裡先總結
提高效率的 Android Studio 技巧匯總,androidstudio這是從Philippe Breault的系列文章《Android Studio Tips O
Android界面架構(Activity,PhoneWiondow,De
利用bintray-release插件上傳到Bintray- HTTP/