中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android圖片加載庫的理解

發布時間:2020-07-22 10:37:42 來源:網絡 閱讀:347 作者:胡壯壯 欄目:移動開發

    

ImageLoader設計原理

ImageLoader的工作原理:在顯示圖片的時,它會先在內存中查找,如果沒有就去本地查找,如果還沒有,就開一個新的線程去下載這張圖片,下載成功會把圖片同時緩存在內存和本地。

我們在基于這個原理,在每次退出一個頁面時候,把ImageLoader內存中緩存全部清除,這樣就節省了大量內存,反正下次再用到的時候從本地再取出來就行了。需要說明的是,由于ImageLoader對圖片是軟引用的形式,所以在內存中的圖片會存在內存不足的時候被系統回收。

總設計圖:

Android圖片加載庫的理解

Android圖片加載庫的理解

ImageLoader流程圖

Android圖片加載庫的理解

Android圖片加載庫的理解

ImageLoader的使用

ImageLoader由三大組件組成:

  1. ImagaLoaderConfiguaration——對圖片緩存進行總體配置,包含內存緩存的大小,本地緩存的大小和位置、日志、下載策略(FIFO還是LIFO)等。

  2. ImageLoader——一般使用displayImage來把URL對應的圖片顯示在ImageView上。

  3. DisplayImageOptions——在每個頁面需要顯示圖片的地方,控制如何顯示的細節,比如指定下載時的默認圖、是否將緩存放到內存或本地磁盤。

從三者的協作關系上看,他們有點像廚房規定、廚師、客戶個人口味之間的關系。ImageLoaderConfiguration就像是廚房里面的規定,每一個廚師要怎么著裝,要怎么保持廚房的干凈,這是針對每一個廚師都適用的規定,而且不允許個性化改變。ImageLoader就像是具體做菜的廚師,負責具體菜譜的制作。DisplayImageOptions就像每個客戶的偏好,根據客戶是重口味還是清淡,每一個p_w_picpathLoader根據DisplayImageOptions的要求具體執行。

ImagaLoaderConfiguaration

示例代碼:

Android圖片加載庫的理解

// DON'T COPY THIS CODE TO YOUR PROJECT! This is just example of ALL options using.// See the sample project how to use ImageLoader correctly.File cacheDir =StorageUtils.getCacheDirectory(context);ImageLoaderConfiguration config =newImageLoaderConfiguration.Builder(context)
        .memoryCacheExtraOptions(480, 800) // default = device screen dimensions
        .diskCacheExtraOptions(480, 800, null)
        .taskExecutor(...)
        .taskExecutorForCachedImages(...)
        .threadPoolSize(3) // default
        .threadPriority(Thread.NORM_PRIORITY-2) // default
        .tasksProcessingOrder(QueueProcessingType.FIFO) // default        .denyCacheImageMultipleSizesInMemory()
        .memoryCache(newLruMemoryCache(2*1024*1024))
        .memoryCacheSize(2*1024*1024)
        .memoryCacheSizePercentage(13) // default
        .diskCache(newUnlimitedDiskCache(cacheDir)) // default
        .diskCacheSize(50*1024*1024)
        .diskCacheFileCount(100)
        .diskCacheFileNameGenerator(newHashCodeFileNameGenerator()) // default
        .p_w_picpathDownloader(newBaseImageDownloader(context)) // default
        .p_w_picpathDecoder(newBaseImageDecoder()) // default
        .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default        .writeDebugLogs()
        .build();

Android圖片加載庫的理解

可以看到ImagaLoaderConfiguaration的職責就是記錄相關的配置,它的內部就是一些字段的集合。

DisplayImageOptions

每一個ImageLoader.displayImage(...)都可以使用DisplayImageOptions,具體配置代碼如下:

Android圖片加載庫的理解

// DON'T COPY THIS CODE TO YOUR PROJECT! This is just example of ALL options using.// See the sample project how to use ImageLoader correctly.DisplayImageOptions options = new DisplayImageOptions.Builder()
        .showImageOnLoading(R.drawable.ic_stub) // resource or drawable
        .showImageForEmptyUri(R.drawable.ic_empty) // resource or drawable
        .showImageOnFail(R.drawable.ic_error) // resource or drawable
        .resetViewBeforeLoading(false)  // default
        .delayBeforeLoading(1000)
        .cacheInMemory(false) // default
        .cacheOnDisk(false) // default        .preProcessor(...)
        .postProcessor(...)
        .extraForDownloader(...)
        .considerExifParams(false) // default
        .p_w_picpathScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default
        .bitmapConfig(Bitmap.Config.ARGB_8888) // default        .decodingOptions(...)
        .displayer(new SimpleBitmapDisplayer()) // default
        .handler(new Handler()) // default
        .build();

Android圖片加載庫的理解

ImageLoader

最終使用時候,簡單幾句就行了,傳入一個ImageView控件

ImageLoader p_w_picpathLoader = ImageLoader.getInstance(); // Get singleton instance// Load p_w_picpath, decode it to Bitmap and display Bitmap in ImageView (or any other view 
//  which implements ImageAware interface)p_w_picpathLoader.displayImage(p_w_picpathUri, p_w_picpathView);

又或者直接

Android圖片加載庫的理解

// Load p_w_picpath, decode it to Bitmap and return Bitmap to callbackp_w_picpathLoader.loadImage(p_w_picpathUri, new SimpleImageLoadingListener() {
    @Override    public void onLoadingComplete(String p_w_picpathUri, View view, Bitmap loadedImage) {        // Do whatever you want with Bitmap    }
});

Android圖片加載庫的理解

ImageLoader優化

盡管ImageLoader很強大,但一直把圖片緩存在內存中,會導致內存占用過高。雖然對圖片的引用是軟引用,軟引用在內存不夠的時候會被GC,但我們還是希望減少GC的次數,所以要經常手動清理ImageLoader中的緩存。

比如,我們經常在做項目的時候,會有一個AppBaseActivity的基類,這樣我們可以在基類的onDestroy方法中,執行ImageLoader的clearMemoryCache方法,以確保頁面銷毀時,把為了顯示這個頁面而增加的內存緩存清除,這樣即使到了下個頁面要復用之前加載過的圖片,雖然內存沒有了,根據ImageLoader的緩存策略,在本地磁盤上還是能被找到的。

比如:

 

protected void onDestroy() {        //回收該頁面緩存在內存的圖片        p_w_picpathLoader.clearMemoryCache(); 
        super.onDestroy();
}

Fresco介紹

簡介:

Fresco 是一個強大的圖片加載組件。它是Facebook開源的圖片加載庫

Fresco 中設計有一個叫做 p_w_picpath pipeline 的模塊。它負責從網絡,從本地文件系統,本地資源加載圖片。為了最大限度節省空間和CPU時間,它含有3級緩存設計(2級內存,1級文件)。

Fresco 中設計有一個叫做 Drawees 模塊,方便地顯示loading圖,當圖片不再顯示在屏幕上時,及時地釋放內存和空間占用。

Fresco 支持 Android2.3(API level 9) 及其以上系統。

 

流程圖:

Android圖片加載庫的理解

 

Android圖片加載庫的理解

 

原理:

Fresco 設計了p_w_picpath pipeline 的概念,它負責先后檢查內存,磁盤文件,如果都沒有再老老實實從網絡下載圖片。

主要有個三層緩存的概念

第一層:Bitmap緩存

在Android 5.0系統中,考慮到內存管理有了很大改進,所以 Bitmap緩存位于Java的heap中,而在Android 4.X或更低的系統中,Bitmap緩存位于ashmem中,而不是位于Java的heap中,這意味著圖片的創建和回收不會引發過多的GC,從而讓APP運行的更快。

第二層:內存緩存

內存緩存中存儲了圖片的原始壓縮格式,從內存緩存中取出的圖片,在顯示前必須先解碼,當APP切換到后臺時,內存緩存也會被清空。

第三層:磁盤緩存

又名本地緩存,磁盤緩存中存儲的也是圖片的原始壓縮格式,在使用前也要先解碼,當APP切換到后臺時,磁盤緩存不會丟失,即使關機也不會。

 

使用:

為了下載網絡圖片,請確保在 AndroidManifest.xml 中有以下權限:

<uses-permission android:name="android.permission.INTERNET"/>

在 Application 初始化時,在應用調用 setContentView() 之前,進行初始化:

Fresco.initialize(context);

在xml布局文件中, 加入命名空間:

Android圖片加載庫的理解

<!-- 其他元素 --><LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fresco="http://schemas.android.com/apk/res-auto">加入SimpleDraweeView:<com.facebook.drawee.view.SimpleDraweeView    android:id="@+id/my_p_w_picpath_view"
    android:layout_width="20dp"
    android:layout_height="20dp"
    fresco:placeholderImage="@drawable/my_drawable"
  />

Android圖片加載庫的理解

開始加載圖片

Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/fresco-logo.png");
SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_p_w_picpath_view);
draweeView.setImageURI(uri);

圖片策略優化

我們這里說的圖片,是根據服務端的接口返回的圖片URL地址開啟一個線程下載到APP本地并顯示的,很多APP崩潰的原因就是圖片的問題沒處理好。那么就有一些相關解決方案策略,如下。

  1. 要確保下載的每張圖,都符合ImageView控件的大小。可以事先準備很多套不同的分辨率的圖片,然后每次根據URL請求圖片時,都要額外在URL上加兩個參數,width和height,從而要求服務器返回其中某一個張圖,比如:http://www.aaa.com/a.png?width=100&height=50

  2. 低流量模式。在2G和3G網絡環境下,我們應該適當降低圖片的質量,降低圖片質量,相應的圖片大小也會降低,簡稱低流量模式,比如在請求網址中再添加一個參數,叫做quality,在2G網絡下這個值為50%,在3G網絡情況下,這個值為70%,這樣就會將JPG圖片質量降低為50%或70%。

  3. 極速模式。發現在2G和3G網絡環境下,大部分用戶對圖片不感興趣,我們可以設計一些只有文字的頁面,這種頁面稱呼為極速模式,以節省流量。

小結

本篇主要介紹了第三方圖片加載庫的原理和使用方法,特別是ImageLoader的介紹,因為圖片顯示在APP中是很常見的應用場景,況且ImageLoader已經封裝好了一些類和方法。我們可以直接拿來用了。而不用重復去寫了。如果自己去寫一個的話,這方面的程序還是比較麻煩的,要考慮多線程緩存,內存溢出等很多方面,再說這么多程序都在用,說明穩定性還是可靠的,類似這種工具類能用穩定成熟的,我們作為一名開發人員,專注度還是在應用業務開發上。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

镇远县| 修水县| 屏南县| 保德县| 郯城县| 济源市| 乡宁县| 阿拉尔市| 昭通市| 黄石市| 木里| 庆元县| 德庆县| 宁城县| 临武县| 轮台县| 新野县| 阳东县| 神木县| 沽源县| 宜阳县| 临颍县| 红安县| 金堂县| 平果县| 江口县| 油尖旺区| 多伦县| 任丘市| 抚宁县| 革吉县| 墨竹工卡县| 额尔古纳市| 平阳县| 新和县| 贺州市| 岢岚县| 雅江县| 临江市| 连平县| 衡山县|