Glide Module 案例: 通過加載自定義大小圖片優(yōu)化
原文:Glide Module Example: Optimizing By Loading Images In Custom Sizes
作者:Norman Peitek
翻譯:Dexter0218
在過去的幾篇文章中,我們已經(jīng)看了大量使用Glide module自定義Glide的內(nèi)容。今天我們要展示最后一個(gè)例子,可能是最有趣的一個(gè):如何從你的服務(wù)器請(qǐng)求特定尺寸的圖片。
Glide 系列概覽
- 入門簡介
- 高級(jí)加載
- 適配器(ListView, GridView)
- 占位圖& 淡入淡出動(dòng)畫
- 圖片大小 & 縮放
- 播放GIF & 視頻
- 緩存基礎(chǔ)
- 請(qǐng)求優(yōu)先級(jí)
- 縮略圖
- 回調(diào):定制view中使用SimpleTarget和ViewTarget
- 通知欄和桌面小控件的圖片加載
- 異常: 調(diào)試和報(bào)錯(cuò)處理
- 自定義變換
- 用animate()定制動(dòng)畫
- 整合網(wǎng)絡(luò)協(xié)議棧
- 用Modules定制Glide
- Glide Module 案例: 接受自簽名HTTPS證書
- Glide Module 案例: 自定義緩存
- Glide Module 案例: 通過加載自定義大小圖片優(yōu)化
- 動(dòng)態(tài)使用 Model Loaders
- 如何旋轉(zhuǎn)圖片
- 系列綜述
為何請(qǐng)求特定尺寸圖片
我們?cè)谧龅淖钚马?xiàng)目用到一個(gè)媒體服務(wù)器,提供非常高的分辨率圖片服務(wù)(圖片分辨率在6000x4500像素)。我們可以使用直接鏈接到源文件,在考慮設(shè)備帶寬、內(nèi)存和電池的時(shí)候是相當(dāng)?shù)托У?。即使在今天的設(shè)備上顯示高分辨率,對(duì)于顯示如此極端的分辨率,還是沒有任何好處。因此Glide總是測(cè)量ImageView的尺寸,然后降低圖片的內(nèi)存消耗以匹配它。然而,無法避免要去下載和計(jì)算,完成降低圖片大小的任務(wù)。因此,媒體服務(wù)器有一個(gè)新特性:它可以提供指定分辨率的圖片。通過下面的方法實(shí)現(xiàn):
// previous way: we directly accessed the images
https://futurestud.io/images/logo.png
// new way, server could handle additional parameter and provide the image in a specific size
// in this case, the server would serve the image in 400x300 pixel size
https://futurestud.io/images/logo.png?w=400&h=300
媒體服務(wù)器在磁盤上保存了之前計(jì)算的大小,如果之前沒有請(qǐng)求,可以在服務(wù)器上快速縮放圖片?,F(xiàn)在,Android邊的初始化實(shí)現(xiàn)計(jì)算了ImageView的大小,然后讓Glide的請(qǐng)求帶有鏈接URL (如 ../logo.png?w=400&h=300),像之前介紹的一樣。這樣的方法奏效了,但是有點(diǎn)太復(fù)雜,特別是如果你認(rèn)為Glide在這里提供幫助的話。
另一個(gè)自定義GlideModule
是的,當(dāng)然,我們會(huì)聲明一個(gè)新的Glide module。在這個(gè)案例中,我們必須用Glide.register()方法向Glide注冊(cè)一個(gè)新的模型:
public class CustomImageSizeGlideModule implements GlideModule {
@Override public void applyOptions(Context context, GlideBuilder builder) {
// nothing to do here
}
@Override public void registerComponents(Context context, Glide glide) {
glide.register(CustomImageSizeModel.class, InputStream.class, new CustomImageSizeModelFactory());
}
}
.register()調(diào)用設(shè)置Glide去理解針對(duì)CustomImageSizeModel接口的所有的請(qǐng)求。所以這行你可以創(chuàng)建并傳遞一個(gè)CustomImageSizeModel的實(shí)例到Glide。為了處理這個(gè)新的自定義模型,我們必須寫一個(gè)CustomImageSizeModelFactory類,創(chuàng)建一個(gè)我們模型請(qǐng)求的handler的實(shí)例。
總之,在你完成上面的添加Glide module后,你應(yīng)該有兩個(gè)類。第一個(gè)是CustomImageSizeModel:
public interface CustomImageSizeModel {
String requestCustomSizeUrl(int width, int height);
}
CustomImageSizeModel只是一個(gè)接口,添加寬度和高度作為參數(shù)。那樣,我們可以從媒體服務(wù)器請(qǐng)求精確像素的圖片。另一個(gè)類是CustomImageSizeModelFactory:
private class CustomImageSizeModelFactory implements ModelLoaderFactory<CustomImageSizeModel, InputStream> {
@Override
public ModelLoader<CustomImageSizeModel, InputStream> build(Context context, GenericLoaderFactory factories) {
return new CustomImageSizeUrlLoader( context );
}
@Override
public void teardown() {
}
}
這個(gè)類只是實(shí)現(xiàn)Glide的ModelLoaderFactory接口,它創(chuàng)建了我們CustomImageSizeUrlLoader的一個(gè)新實(shí)例,一旦Glide請(qǐng)求被創(chuàng)建,將會(huì)去處理圖片加載:
public class CustomImageSizeUrlLoader extends BaseGlideUrlLoader<CustomImageSizeModel> {
public CustomImageSizeUrlLoader(Context context) {
super( context );
}
@Override
protected String getUrl(CustomImageSizeModel model, int width, int height) {
return model.requestCustomSizeUrl( width, height );
}
}
當(dāng)我們的新Glide module完成,并準(zhǔn)備自定義大小請(qǐng)求。我們已經(jīng)完成了Glide module邊的所有事情,但是我們實(shí)際上還沒有創(chuàng)建CustomImageSizeModel接口的實(shí)現(xiàn)。為了用CustomImageSizeModel傳遞請(qǐng)求到Glide,我們需要一個(gè)類,創(chuàng)建定制圖片大小的URL:
public class CustomImageSizeModelFutureStudio implements CustomImageSizeModel {
String baseImageUrl;
public CustomImageSizeModelFutureStudio(String baseImageUrl) {
this.baseImageUrl = baseImageUrl;
}
@Override
public String requestCustomSizeUrl(int width, int height) {
// previous way: we directly accessed the images
// https://futurestud.io/images/logo.png
// new way, server could handle additional parameter and provide the image in a specific size
// in this case, the server would serve the image in 400x300 pixel size
// https://futurestud.io/images/logo.png?w=400&h=300
return baseImageUrl + "?w=" + width + "&h=" + height;
}
}
上面的CustomImageSizeModelFutureStudio類中,我們已經(jīng)實(shí)現(xiàn)了根據(jù)添加的寬高參數(shù)創(chuàng)建圖片URL的邏輯。最終,我們可以創(chuàng)建這個(gè)類的實(shí)例,并創(chuàng)建一個(gè)Glide請(qǐng)求:
String baseImageUrl = "https://futurestud.io/images/example.png";
CustomImageSizeModel customImageRequest = new CustomImageSizeModelFutureStudio( baseImageUrl );
Glide
.with( context )
.load( customImageRequest )
.into( imageView2 );
正如上面所見,你不需要出傳遞準(zhǔn)確的尺寸。Glide會(huì)測(cè)量ImageView并用我們的請(qǐng)求傳遞它。現(xiàn)在,服務(wù)器會(huì)用一個(gè)完美優(yōu)化的圖片作為響應(yīng)!
當(dāng)然,你可以只添加額外的CustomImageSizeModel模型實(shí)現(xiàn),如果你有多個(gè)服務(wù)器,它們使用不同的邏輯創(chuàng)建URL。只要?jiǎng)?chuàng)建一個(gè)CustomImageSizeModel實(shí)現(xiàn),并傳遞到你的Glide請(qǐng)求中。你想用多少model實(shí)現(xiàn)就可以用多少!
展望
本文中,你已經(jīng)看到了如何降低圖像請(qǐng)求開銷的重要部分。你的用戶樂于關(guān)注他們的電池狀態(tài)和數(shù)據(jù)使用情況。不幸地是,你必須在服務(wù)器端支持這個(gè)功能。不過,Glide讓Android側(cè)非常簡單。初始化的步驟有點(diǎn)復(fù)雜,但是一但理解了概念,是非常有用的。
本文展示給你的方法:會(huì)用到在每個(gè)單獨(dú)請(qǐng)求上。如果你在圖像的URL上混合使用,哪個(gè)可以調(diào)整大小和圖像的URL,不能調(diào)整?下期,我們將告訴你在一個(gè)請(qǐng)求上如何動(dòng)態(tài)地應(yīng)用相同的思想。