日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

从设计到实现,一步步教你实现Android-Universal-ImageLoader-辅助类

發布時間:2023/11/27 生活经验 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从设计到实现,一步步教你实现Android-Universal-ImageLoader-辅助类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

通過前面幾篇博文。我們分析了 AUI 的緩存、工具類、顯示與載入這幾個方面的代碼。今天呢,我們繼續研究 AUI 的源代碼,學習當中的核心輔助工具類。

希望大家能在里面學到東西哈。

Download

要下載一張圖片,我們想象須要什么哈:首先我們得設定支持的協議。得有下載的鏈接。由對應的下載鏈接去下載圖片。進而得到圖片的輸入流,剩下的就交給圖片的顯示/載入類處理啦。

那么我們能夠設計出以下的接口:

public interface ImageDownloader {InputStream getStream(String imageUri, Object extra) throws IOException;public enum Scheme {HTTP("http"), HTTPS("https"), FILE("file"), CONTENT("content"), ASSETS("assets"), DRAWABLE("drawable"), UNKNOWN("");private String scheme;private String uriPrefix;Scheme(String scheme) {this.scheme = scheme;uriPrefix = scheme + "://";}public static Scheme ofUri(String uri) {if (uri != null) {for (Scheme s : values()) {if (s.belongsTo(uri)) {return s;}}}return UNKNOWN;}private boolean belongsTo(String uri) {return uri.toLowerCase(Locale.US).startsWith(uriPrefix);}public String wrap(String path) {return uriPrefix + path;}public String crop(String uri) {if (!belongsTo(uri)) {throw new IllegalArgumentException(String.format("URI [%1$s] doesn't have expected scheme [%2$s]", uri, scheme));}return uri.substring(uriPrefix.length());}}
}

看到這里大家可能會疑惑了,我們不是設計接口么,為啥要搞個枚舉類型,并且還在里面搞那么多亂七八糟的東西……事實上。假設大家有看過《Thinking In Java》的話就會知道。在 Java 中,enum 實際上就是一個類。由于 enum 定義后的枚舉類在編譯時默認繼承 java.lang.Enum 類。而該枚舉類會自己主動被加上 final 關鍵字修飾。這也使得枚舉類無法被繼承。更詳細的解釋大家能夠自行 Google 哈。

那么為什么要在 ImageDownloader 里引入這個枚舉類呢?我們最好還是先看看枚舉類內究竟有什么。在枚舉類 Scheme 中,主要有四個方法,而這四個方法都用于處理 Uri,如:裁減 Uri、加入 Uri 前綴、推斷 Uri。也就是說,Scheme 的抽象職責是:對 Uri 進行修飾。

而 Scheme 對 Uri 的修飾結果將交給 ImageDownloader 完畢下載操作。

換言之,Scheme 的抽象與 ImageDownloader 的抽象實際上是不一致的(ImageDownloader 的抽象是下載圖片,而下載圖片所需的 Uri 須要進行什么處理才干被 ImageDownloader 使用,并完畢下載事實上不重要),為了讓減少類的耦合度,我們在 ImageDownloader 的內部實現了 Scheme 類。

那么有人可能會問了,那我們另外創建一個類不行么?就我的理解來看,肯定是能夠的。由于 Scheme 本質上也是一個類,我們新創建一個類。聲明為 final 類。加入對應的靜態常量、方法。事實上效果也是一樣的。

那作者為什么要這么干呢?看過《Effective Java》的朋友可能會知道,實現單例的最佳方法就是使用 enum,詳細的解釋大家自己去查吧。我就不在這里多說了。

那么作者在這里實際上就是在接口內部定義了一個單例。

What is an efficient way to implement a singleton pattern in Java?

BaseImageDownloader 實現了 ImageDownloader 接口,并且依據我們的需求實現了對應的圖片下載細節,詳細沒什么好解說的,大家能夠自行閱讀源代碼哈~

Listener

在 AUI 中,實際上須要用到的 Listener 并不多,畢竟圖片載入僅僅是一個非常小的功能模塊嘛。那么 AUI 究竟包括了什么 Listener 呢?

  • 圖片載入監聽器:監聽圖片載入的開始、結束、失敗、取消
  • 圖片載入進度監聽器:監聽圖片載入的進度
  • 圖片載入滾動監聽器:當圖片載入正在進行,若發生滾動,則停止載入,換言之,僅僅載入當前屏幕顯示的圖片。圖片滾動過程的圖片則不載入。

可能有人會認為非常奇怪。為什么圖片載入監聽器和圖片載入進度監聽器要分開實現。事實上我也想不懂。希望有人能給我個解釋……

Assist

在 assist 里面有幾個類我們在之前的博文中已經有提過了,我就不再這反復拉。

比較簡單的類我也會一筆帶過。希望大家理解哈。

deque

在這里面都是一些雙端隊列。比如 LinkedBlockingDeque、LIFOLinkedBlockingDeque。雙端隊列的對應知識。以及詳細實現我相信不用我在這里廢話了,畢竟數據結構的課程中一定會說到這個知識點,這也是個主要的、必須掌握的數據結構。

那么在這里我們須要了解什么呢?那就是:為什么引入雙端隊列作為 AUI 的數據結構,雙端隊列較之其它數據結構在這個應用場景下有什么長處。

我們最好還是先看看 Deque 在哪里被用到吧,在 AUI 庫中搜索發現。DefaultConfigurationFactory 調用了 Deque。

那么 DefaultConfigurationFactory 究竟是什么呢?

從該類的命名以及內部的方法名我們能夠知道。DefaultConfigurationFactory 就是 AUI 默認的配置工廠類,假設開發人員沒有自己定義對應的配置選項的話,AUI 就會使用這個類所設置的默認選項,完畢對應的載入、下載、緩存等等……

最好還是看看以下的代碼段:

    public static Executor createExecutor(int threadPoolSize, int threadPriority,QueueProcessingType tasksProcessingType) {boolean lifo = tasksProcessingType == QueueProcessingType.LIFO;BlockingQueue<Runnable> taskQueue =lifo ? new LIFOLinkedBlockingDeque<Runnable>() : new LinkedBlockingQueue<Runnable>();return new ThreadPoolExecutor(threadPoolSize, threadPoolSize, 0L, TimeUnit.MILLISECONDS, taskQueue,createThreadFactory(threadPriority, "uil-pool-"));}

在這段代碼中。我們會獲得線程池,并且用 LIFOLinkedBlockingDeque 作為線程的處理隊列。也就是說,在 AUI 庫中。雙端隊列這個數據結構是用來完畢 AUI 線程處理的。那么為什么要選擇雙端隊列,為什么又選擇 LIFOLinkedBlockingDeque 作為默認選項呢?

之所以選擇雙端隊列。是由于 ThreadPoolExecutor 使用的是生產者-消費者模式,在 ThreadPoolExecutor 類內部使用 BlockingQueue 作為任務處理隊列能滿足生產者-消費者模式對任務存儲數據結構的要求。而在我們的 assist 中。LIFOLinkedBlockingDeque 是 LinkedBlockingDeque 的子類。而 LinkedBlockingDeque 實現了 BlockingDeque 接口,BlockingDeque 接口又繼承于 BlockingQueue。

Others

在 assist 中剩下的輔助類我認為都挺簡單的,都是一些基本 API 調用的簡化。大家自己看看源代碼都能看懂的~

轉載于:https://www.cnblogs.com/brucemengbm/p/7029281.html

總結

以上是生活随笔為你收集整理的从设计到实现,一步步教你实现Android-Universal-ImageLoader-辅助类的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。