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