前言:
前面總結學習了圖片的使用以及Lru演算法,今天來學習一下比較優秀的圖片快取開源框架。技術本身就要不斷的更迭,從最初的自己使用SoftReference實現自己的圖片快取,到後來做電商專案自己的實現方案不能滿足專案的需求改用Afinal,由於Afinal不再維護而選擇了師出同門的Xutils,中間也接觸過別的開源框架比如Picasso,對Picasso的第一次印象就不太好,初次接觸是拿到了公司剛從外包公司接手過來的圖片社交類app,對記憶體佔用太大,直接感受就是導致ListView滑動有那麼一點卡頓,老牌的圖片快取框架universalImageLoader聽說過一直沒有真正使用過,之前專案都很小,差不多幾百萬級別的app,一直使用的都是Xutils,最近覺得專案大起來了,萬一Xutils不維護了或者說要求支援的圖片格式多起來的時候,可能Xutils就不是最佳選擇了,這也是來學習Gilde的根本動機吧。其實本來想著去學習Facebook的Fresco圖片框架,但是簡單的看了一下,需要連同自定義控制元件一起使用,功能雖然強大,但是對於已經在維護的專案修改成本那可不是一般的高,以後有興趣在學習吧!
圖片快取相關部落格地址:
Glide簡介:
Glide 是 Google 員工的開源專案, Google I/O 上被推薦使用,一個高效、開源、Android裝置上的媒體管理框架,它遵循BSD、MIT以及Apache 2.0協議釋出。Glide具有獲取、解碼和展示視訊劇照、圖片、動畫等功能,它還有靈活的API,這些API使開發者能夠將Glide應用在幾乎任何網路協議棧裡。建立Glide的主要目的有兩個,一個是實現平滑的圖片列表滾動效果,另一個是支援遠端圖片的獲取、大小調整和展示。
gitHub地址:https://github.com/bumptech/glide
Glide特點
-
使用簡單
-
可配置度高,自適應程度高
-
支援常見圖片格式 Jpg png gif webp
-
支援多種資料來源 網路、本地、資源、Assets 等
-
高效快取策略 支援Memory和Disk圖片快取 預設Bitmap格式採用RGB_565記憶體使用至少減少一半
-
生命週期整合 根據Activity/Fragment生命週期自動管理請求
-
高效處理Bitmap 使用Bitmap Pool使Bitmap複用,主動呼叫recycle回收需要回收的Bitmap,減小系統回收壓力
Glide簡單使用
1.)新增引用 build.gradle 中新增配置
compile 'com.github.bumptech.glide:glide:3.7.0'
2.)設定繫結生命週期
我們可以更加高效的使用Glide提供的方式進行繫結,這樣可以更好的讓載入圖片的請求的生命週期動態管理起來
Glide.with(Context context);// 繫結Context Glide.with(Activity activity);// 繫結Activity Glide.with(FragmentActivity activity);// 繫結FragmentActivity Glide.with(Fragment fragment);// 繫結Fragment
3. )簡單的載入圖片例項
Glide.with(this).load(imageUrl).into(imageView);
4.)設定載入中以及載入失敗圖片
api裡面對placeholder()、error()函式中有多型實現 用的時候可以具體的熟悉一下
Glide.with(this).load(imageUrl).placeholder(R.mipmap.ic_launcher).error(R.mipmap.ic_launcher).into(imageView);
5.)設定跳過記憶體快取
Glide.with(this).load(imageUrl).skipMemoryCache(true).into(imageView);
6.)設定下載優先順序
Glide.with(this).load(imageUrl).priority(Priority.NORMAL).into(imageView);
7.)設定快取策略
Glide.with(this).load(imageUrl).diskCacheStrategy(DiskCacheStrategy.ALL).into(imageView);
策略解說:
all:快取源資源和轉換後的資源
none:不作任何磁碟快取
source:快取源資源
result:快取轉換後的資源
8.)設定載入動畫
api也提供了幾個常用的動畫:比如crossFade()
Glide.with(this).load(imageUrl).animate(R.anim.item_alpha_in).into(imageView);
R.anim.item_alpha_in
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:duration="500" android:fromAlpha="0.0" android:toAlpha="1.0"/> </set>
9.)設定縮圖支援
這樣會先載入縮圖 然後在載入全圖
Glide.with(this).load(imageUrl).thumbnail(0.1f).into(imageView);
10.)設定載入尺寸
Glide.with(this).load(imageUrl).override(800, 800).into(imageView);
11.)設定動態轉換
Glide.with(this).load(imageUrl).centerCrop().into(imageView);
api提供了比如:centerCrop()、fitCenter()等函式也可以通過自定義Transformation,舉例說明:比如一個人圓角轉化器
public class GlideRoundTransform extends BitmapTransformation { private float radius = 0f; public GlideRoundTransform(Context context) { this(context, 4); } public GlideRoundTransform(Context context, int dp) { super(context); this.radius = Resources.getSystem().getDisplayMetrics().density * dp; } @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { return roundCrop(pool, toTransform); } private Bitmap roundCrop(BitmapPool pool, Bitmap source) { if (source == null) return null; Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888); if (result == null) { result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(result); Paint paint = new Paint(); paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP)); paint.setAntiAlias(true); RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight()); canvas.drawRoundRect(rectF, radius, radius, paint); return result; } @Override public String getId() { return getClass().getName() + Math.round(radius); } }
具體使用
Glide.with(this).load(imageUrl).transform(new GlideRoundTransform(this)).into(imageView);
12.)設定要載入的內容
專案中有很多需要先下載圖片然後再做一些合成的功能,比如專案中出現的圖文混排,該如何實現目標下
Glide.with(this).load(imageUrl).centerCrop().into(new SimpleTarget<GlideDrawable>() { @Override public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) { imageView.setImageDrawable(resource); } });
13 .)設定監聽請求介面
Glide.with(this).load(imageUrl).listener(new RequestListener<String, GlideDrawable>() { @Override public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) { return false; } @Override public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) { //imageView.setImageDrawable(resource); return false; } }).into(imageView);
設定監聽的用處 可以用於監控請求發生錯誤來源,以及圖片來源 是記憶體還是磁碟
15.)設定動態GIF載入方式
Glide.with(this).load(imageUrl).asBitmap().into(imageView);//顯示gif靜態圖片 Glide.with(this).load(imageUrl).asGif().into(imageView);//顯示gif動態圖片
16.)快取的動態清理
Glide.get(this).clearDiskCache();//清理磁碟快取 需要在子執行緒中執行 Glide.get(this).clearMemory();//清理記憶體快取 可以在UI主執行緒中進行
小結:
以上是Glide的常規用法,基本上滿足開發需要了,然後再去學習一下其他相關知識。