基於Glide的二次封裝
更多程式碼可以查詢本人GitHub:歡迎閱讀,star點起來。
Glide二次封裝庫原始碼
前言
為什麼選擇Glide?
- Glide 輕量級
- 速度快
- 可以根據所需載入圖片的大小自動適配所需解析度的圖
- 支援多種格式圖片(靜態webp,動態gif,jpeg,jpg,png)
- 支援多種資料來源圖片(url,drawable,src,file,asserts,raw)
- Google主導
已經很方便了,為啥還要封裝?
- 避免以後換框架的時候需要改的地方太多。如果封裝了只需要改封裝的方法而不會影響到所有的程式碼。
- 入口統一,所有圖片載入都在這一個地方管理,一目瞭然,即使有什麼改動我也只需要改這一個類就可以了。
- 雖然現在的第三方庫已經非常好用,但是如果我們看到第三方庫就拿來用的話,很可能在第三方庫無法滿足業務需求或者停止維護的時候,發現替換庫,工作量可見一斑。這就是不封裝在切庫時面臨的窘境!
- 外部表現一致,內部靈活處理原則
初識Glide
Glide配置
1、 在build.gradle中新增依賴:
dependencies {
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.android.support:support-v4:19.1.0'
}
2、混淆
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
3、許可權
如果是聯網獲取圖片或者本地儲存需要新增以下許可權:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Glide基本使用
Glide使用一個流介面(Fluent Interface)。用Glide完成一個完整的圖片載入功能請求,需要向其構造器中至少傳入3個引數,分別是:
- with(Context context)- Context是許多Android API需要呼叫的, Glide也不例外。這裡Glide非常方便,你可以任意傳遞一個Activity或者Fragment物件,它都可以自動提取出上下文。
- load(String imageUrl) - 這裡傳入的是你要載入的圖片的URL,大多數情況下這個String型別的變數會連結到一個網路圖片。
- into(ImageView targetImageView) - 將你所希望解析的圖片傳遞給所要顯示的ImageView。
example:
ImageView targetImageView = (ImageView) findViewById(R.id.imageView);
String internetUrl = "http://i.imgur.com/DvpvklR.png";
Glide
.with(context)
.load(internetUrl)
.into(targetImageView);
如何進行二次封裝
明白了為什麼封裝以及基本原理,接下來我們就要開工,大幹一場。
先看一下本人封裝後的基本使用樣式:
ImageLoader.with(this)
.url("http://img.yxbao.com/news/image/201703/13/7bda462477.gif")
.placeHolder(R.mipmap.ic_launcher,false)
.rectRoundCorner(30, R.color.colorPrimary)
.blur(40)
.into(iv_round);
更多屬性我們後再詳細講解使用,主要先來看看具體的封裝。
先看一下uml:
使用者只需要關心ImageLoader就好了,就算裡面封裝的庫更換、更新也沒關係,因為對外的介面是不變的。實際操作中是由實現了ILoader的具體類去操作的,這裡我們只封裝了GlideLoader,其實所有操作都是由ImageLoader下發指令,由GlideLoader具體去實現的。這裡如果想封裝別的第三方庫,只需要實現ILoader自己去完成裡面的方法。
初始化
public static int CACHE_IMAGE_SIZE = 250;
public static void init(final Context context) {
init(context, CACHE_IMAGE_SIZE);
}
public static void init(final Context context, int cacheSizeInM) {
init(context, cacheSizeInM, MemoryCategory.NORMAL);
}
public static void init(final Context context, int cacheSizeInM, MemoryCategory memoryCategory) {
init(context, cacheSizeInM, memoryCategory, true);
}
/**
* @param context 上下文
* @param cacheSizeInM Glide預設磁碟快取最大容量250MB
* @param memoryCategory 調整記憶體快取的大小 LOW(0.5f) / NORMAL(1f) / HIGH(1.5f);
* @param isInternalCD true 磁碟快取到應用的內部目錄 / false 磁碟快取到外部存
*/
public static void init(final Context context, int cacheSizeInM, MemoryCategory memoryCategory, boolean isInternalCD) {
ImageLoader.context = context;
GlobalConfig.init(context, cacheSizeInM, memoryCategory, isInternalCD);
}
從這裡可以看出我們提供了四個構造器,這裡註釋詳細說明了所有引數的用法及意義。
除了初始化,我們還需要在Application中重寫以下方法:
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
// 程式在記憶體清理的時候執行
ImageLoader.trimMemory(level);
}
@Override
public void onLowMemory() {
super.onLowMemory();
// 低記憶體的時候執行
ImageLoader.clearAllMemoryCaches();
}
上面這兩個方法會在下面ImageLoader中介紹到。
你所關心的類–ImageLoader
ImageLoader是封裝好所有的方法供使用者使用的,讓我們看看都有什麼方法:
- ImageLoader.init(Context context) //初始化
- ImageLoader.trimMemory(int level);
- ImageLoader.clearAllMemoryCaches();
- ImageLoader.getActualLoader(); //獲取當前的loader
- ImageLoader.with(Context context) //載入圖片
- ImageLoader.saveImageIntoGallery(DownLoadImageService downLoadImageService) // 儲存圖片到相簿
- ImageLoader.pauseRequests() //取消請求
- ImageLoader.resumeRequests() //回覆的請求(當列表在滑動的時候,呼叫pauseRequests()取消請求,滑動停止時,呼叫resumeRequests()恢復請求 等等)
- ImageLoader.clearDiskCache()//清除磁碟快取(必須在後臺執行緒中呼叫)
- ImageLoader.clearMomoryCache(View view) //清除指定view的快取
- ImageLoader.clearMomory() // 清除記憶體快取(必須在UI執行緒中呼叫)
圖片的各種設定資訊–SingleConfig
我們所設定圖片的所有屬性都寫在這個類裡面。下面我們詳細的看一下:
- url(String url) //url
- file(String filePath) //載入SD卡資源
- file(File file) //載入SD卡資源
- res(int resId) //載入drawable資源
- content(String contentProvider) //載入ContentProvider資源
- raw(String rawPath) //載入raw資源
- asserts(String assertspath) //載入asserts資源
- thumbnail(float thumbnail)//縮圖
- rectRoundCorner(int rectRoundRadiusf) //形狀為圓角矩形時的圓角半徑
- priority(int priority) //優先順序
- error(int errorResId) //錯誤佔位圖
- asSquare() //形狀為正方形
- colorFilter(int color) //顏色濾鏡
- diskCacheStrategy(DiskCacheStrategy diskCacheStrategy) //DiskCacheStrategy.NONE :不快取圖片 /DiskCacheStrategy.SOURCE :快取圖片原始檔/DiskCacheStrategy.RESULT:快取修改過的圖片/DiskCacheStrategy.ALL:快取所有的圖片,預設
ignoreCertificateVerify(boolean ignoreCertificateVerify) // https是否忽略校驗- asCircle()//載入圓形圖片
- placeHolder(int placeHolderResId) //佔位圖
- override(int oWidth, int oHeight) //載入圖片時設定解析度 a
- scale(int scaleMode) // CENTER_CROP等比例縮放圖片,直到圖片的狂高都大於等於ImageView的寬度,然後擷取中間的顯示 ; FIT_CENTER 等比例縮放圖片,寬或者是高等於ImageView的寬或者是高 預設:FIT_CENTER
- animate(int animationId ) 引入動畫
- animate( Animation animation) 引入動畫
- animate(ViewPropertyAnimation.Animator animato) 引入動畫
- asBitmap(BitmapListener bitmapListener)// 使用bitmap不顯示到imageview
- into(View targetView) //展示到imageview
- colorFilter(int filteColor) //顏色濾鏡
- blur(int blurRadius) //高斯模糊
- brightnessFilter(float level) //調節圖片亮度
- grayscaleFilter() //黑白效果
- swirlFilter() //漩渦效果
- toonFilter() //油畫效果
- sepiaFilter() //水墨畫效果
- contrastFilter(float constrasrLevel) //銳化效果
- invertFilter() //膠片效果
- pixelationFilter(float pixelationLevel) //馬賽克效果
- sketchFilter() // //素描效果
- vignetteFilter() //暈映效果
中轉站–GlobalConfig
GlobalConfig類非常簡單主要是選擇Loader的操作,之所以用到這個類是因為方便以後擴充套件。今後我們如果需要使用其他的圖片載入框架,只需要繼承ILoader,然後在GlobalConfig中配置即可。
public class GlobalConfig {
public static void init(Context context, int cacheSizeInM,
getLoader().init(context, cacheSizeInM, memoryCategory, isInternalCD);
}
public static ILoader getLoader() {
if (loader == null) {
//這裡只做了glide的封裝
loader = new GlideLoader();
}
//可以接著做fresco或者picasso
return loader;
}
{
最終的執行者–GlideLoader
GlideLoader實現ILoader介面。在使用的時候我們雖然不用關心這個類,但是瞭解一下主要做了什麼功能還是必要的。
GlideLoader中主要做了兩件事,一個是初始化的實現,一個是出口方法的實現。
初始化的實現
我們在application中呼叫
ImageLoader.init(getApplicationContext());
會最終呼叫到下面這個方法,最終的操作都是在這裡進行的
public class GlideLoader implements ILoader {
/**
* @param context 上下文
* @param cacheSizeInM Glide預設磁碟快取最大容量250MB
* @param memoryCategory 調整記憶體快取的大小 LOW(0.5f) / NORMAL(1f) / HIGH(1.5f);
* @param isInternalCD true 磁碟快取到應用的內部目錄 / false 磁碟快取到外部存
*/
@Override
public void init(Context context, int cacheSizeInM, MemoryCategory memoryCategory, boolean isInternalCD) {
Glide.get(context).setMemoryCategory(memoryCategory); //如果在應用當中想要調整記憶體快取的大小,開發者可以通過如下方式:
GlideBuilder builder = new GlideBuilder(context);
if (isInternalCD) {
builder.setDiskCache(new InternalCacheDiskCacheFactory(context, cacheSizeInM * 1024 * 1024));
} else {
builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, cacheSizeInM * 1024 * 1024));
}
}
}
出口方法的實現
不管最終我們使用的是into() 還是 asBitmap()
最終都會呼叫GlideLoader的request()方法。
request()方法裡面我們主要思路是拿到DrawableTypeRequest,然後根據SingleConfig中的配置資訊進行設定。
@Override
public void request(final SingleConfig config) {
RequestManager requestManager = Glide.with(config.getContext());
DrawableTypeRequest request = getDrawableTypeRequest(config, requestManager);
}
比如:設定圖片伸縮
方法如下:
//先拿到之前的配置資訊。
int scaleMode = config.getScaleMode();
//然後根據配置資訊去對request進行設定。
switch (scaleMode) {
case ScaleMode.CENTER_CROP:
request.centerCrop();
break;
case ScaleMode.FIT_CENTER:
request.fitCenter();
break;
default:
request.fitCenter();
break;
}
其他的方法與此方法相同,就不在這做詳細說明了。
總結
總結一下,其實主要思路就是在GlobalConfig中選擇使用哪一個圖片載入庫,然後將使用者的所用設定資訊儲存在SingleConfig中,然後在具體的Loader中去實現,本文使用的Glide,也可以增加FrescoLoader,只需要實現ILoader然後實現request()方法去通過DrawableTypeRequest設定就好了。
更多程式碼可以查詢本人GitHub:歡迎閱讀,star點起來。
Glide二次封裝庫原始碼
看一下效果哦:
到這裡我們的封裝就結束了,就可以愉快的使用了,歡迎大家提出意見與建議。
使用
在gradle中新增如下配置
compile 'com.libin.imageloader:ImageLoader:1.0.3'
在Application中:
ImageLoader.init(getApplicationContext());
為了防止oom,加入如下程式碼,清理記憶體:
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
ImageLoader.trimMemory(level);
}
@Override
public void onLowMemory() {
super.onLowMemory();
ImageLoader.clearAllMemoryCaches();
}
混淆
在proguard-rules中新增如下
-dontwarn okio.**
由於具體使用文章較長,具體如何使用詳細API介紹請移步本人下一篇部落格
Glide二次封裝庫的使用
更多程式碼可以查詢本人GitHub:歡迎閱讀,star點起來。
Glide二次封裝庫原始碼
掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~
掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~
掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~