過去幾周,我們已經看到了用 Glide module 來為 Glide 做各種各樣的自定義。今天我們將會為你展示最后一個實例,但這可能是最有趣的一個了:從你的服務端在指定的尺寸下如何去請求圖片。
**為何要在指定的尺寸下請求圖片**?
在一個最近的項目中我們與一個多媒體服務端工作,它也是圖片服務端,提供了非常高的圖像質量(圖像可能有 6000x4500 像素)。雖然我們可以直接用鏈接去拿源文件,但這對于設備的帶寬,內存和電池來說,這么做是非常低效的。即使今天的設備有著非常高的分辨率顯示屏,有這么高的一個分辨率沒有任何好處。這就是為什么 Glide 總是測量 `ImageView` 的尺寸,并減少圖像的內存分配大小。所以,這里仍然需要減少下載和計算處理的開銷。因此,這個多媒體服務端給了一個新功能:它可以提供自定義圖像的分辨率。這么想象一下吧:
~~~
// 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
~~~
媒體服務端維護了之前的計算大小在磁盤上,如果沒有請求傳過去,縮放圖像仍然在天上飛呢。現在初步實現了 Android 這邊計算好了 `ImageView` 的大小,然后用 鏈接 URL(就像 `../logo.png?w=400&h=300`)做 Glide 請求。向我們之前給你展現的那樣。這種方式奏效了,但是有點復雜,特別是如果你認為 Glide 在這里提供了幫助。
**另一種自定義 GlideModule?**
當然,我們必須聲明一個新的 Glide module。在這種情況下,我們必須用 `glide.register()` 方法注冊新的 model 到 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()` 調用了 Glide 的配置去給所有的請求,實現 `CustomImageSizeModel` 接口(替換常規的 `GlideUrl` 接口)。所以在這里你可以創建并傳遞一個 `CustomImageSizeModel` 的實例去實現給 Glide。 為了處理這個新的自定義 model。我們要去寫一個 C`ustomImageSizeModelFactory` 類,創建了我們的 model 處理的實例。
綜上所述,在你添加了上述的 Glide module 后,你應該有兩個未知的類。首先是 `CustomImageSizeModel`。
~~~
public interface CustomImageSizeModel {
String requestCustomSizeUrl(int width, int height);
}
~~~
`CustomImageSizeModel` 只是一個接口,它將寬度和高度作為其參數,這是必須的,這樣我們才能從媒體服務端請求精確的像素圖像。第二個未知的類是 `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() {
}
}
~~~
這個類僅僅實現了 Glide 的 `ModelLoaderFactory` 接口。它為我們的 `CustomImageSizeUrlLoader` 類創建了一個新的實例,一旦 Glide 請求被創建,它將負責加載圖像。
~~~
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 已經做完了。我們已經在 Glide module 這邊實現了所有的東西的,但是我們還沒有實際創建` CustomImageSizeModel` 接口的實現。為了用 `CustomImageSizeModel` 傳遞請求給 Glide。我們需要一個雷,它建立了自定義圖片大小的 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` 類中,我們已經實現了建立圖片 URL 的邏輯:附加了高度和寬度的參數。最后,我們可以創建這個類的實例并做一個 Glide 請求:
~~~
String baseImageUrl = "https://futurestud.io/images/example.png";
CustomImageSizeModel customImageRequest = new CustomImageSizeModelFutureStudio( baseImageUrl );
Glide
.with( context )
.load( customImageRequest )
.into( imageView2 );
~~~
正如你看到的,我們不需要傳一個精確的尺寸。Glide 會測量 `ImageView` 然后傳給我們的請求。現在服務端會返回這個圖片的完美的優化后的尺寸了!
當然你可以添加其他的 `CustomImageSizeModel model` 實現。如果你有多個服務端,它們使用了不同的邏輯去簡歷 URL。只需要創建一個新的 `CustomImageSizeModel` 實現然后傳遞它到你的 Glide 請求中。你可以使用很多的 model 去按照你需要的來實現!
**Outlook**?
在這篇博客中,你已經看到如何削減圖像請求的開銷的重要部分。每次你的用戶將會看到他們的電池狀態和存儲數據,他們會愛上你的。不幸的是,你將需要服務端支付。盡管如此,Glide 在 Android 這邊的做法是非常簡單的。初始設置有點復雜,但是一旦你理解了這個概念,它將非常有用!
在這篇博客中我們向你展示的方法有一個問題:它將用在每一個單個請求。如果你在圖像的 URL 中有混合使用的情況,它將重新計算大小,以及圖片的 URL,它不能被調整?下周,我們要向你展示如何以相同的思想動態的在每個請求中應用。
- 前言
- 一開始
- 二加載進階
- 三ListAdapter(ListView, GridView)
- 四占位符 和 漸現動畫
- 五圖片重設大小 和 縮放
- 六顯示 Gif 和 Video
- 七緩存基礎
- 八請求優先級
- 九縮略圖
- 十回調:SimpleTarget 和 ViewTarget 用于自定義視圖類
- 十一加載圖片到通知欄和應用小部件中
- 十二異常:調試和錯誤處理
- 十三自定義轉換
- 十四用 animate() 自定義動畫
- 十五集成網絡棧
- 十六用 Module 自定義
- 十七Module 實例:接受自簽名證書的 HTTPS
- 十八Module 實例:自定義緩存
- 十九Module 實例:用自定義尺寸優化加載的圖片
- 二十動態使用 Model Loader
- 二十一如何旋轉圖像
- 二十二系列綜述