Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> DrySister看妹子應用(第一版)——3.圖片加載優化(寫個圖片緩存小框架)

DrySister看妹子應用(第一版)——3.圖片加載優化(寫個圖片緩存小框架)

編輯:關於Android編程

1.一些BB

上節我們把妹子圖片的數據來源從本地改成了解析Gank提供的接口數據,我們本節想對這個圖片加載類進行優化,比如加上顯示本地圖片的,另外還有一點就是緩存,我們現在用得圖片加載沒有任何緩存可言,每次都是請求後,解析流,即使是同樣的圖片每次都要去請求一次,這顯得有點累贅,把圖片緩存到內存,或者磁盤裡,當訪問相同的圖片資源我們從這裡拿?嗯,好像很有搞頭,那麼本節我們就來寫一個簡單的帶緩存的圖片加載框架吧!嗯,就叫SisterLoader吧!

\

(PS:拖著好久沒更的原因是因為自己最近在看下載相關的東西,還有改BUG寫圖片加載的時候因為一些問題卡住了,抽不出時間解決…)<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxociAvPg0KPGgyIGlkPQ=="2簡單常識科普">2.簡單常識科普

開始寫代碼之前我們先來撸清楚一些概念先:

1)緩存

①引入圖片緩存的目的

答:從網絡加載圖片費時費電費流量,我們希望把一些加載過的圖片可以存起來,
當再次加載時可以復用這個圖片。

②什麼是二級緩存

答:說下需要顯示一張圖片所經歷的邏輯,你就一清二楚了:
需要顯示圖片 ——> 查內存(有的話顯示) —沒有—>查磁盤(有的話顯示) —沒有—>
從網絡加載(顯示出來) ——> 往內存中存一份 ——> 往磁盤存一份

從上我們知道,緩存有兩種,內存緩存和磁盤緩存(SD卡/機身存儲):

內存緩存:一級緩存,優先從這裡拿,緩存文件存儲在data/data/包名/cache目錄下,
以前寫內存緩存的老舊套路是用Map弱引用的Bitmap對象,我翻了翻上上上家公司的祖傳代碼:

public class MemoryCache {

    private static final int MAX_CACHE_COUNT = 30;  //設置最大緩存數

    /**
    Map弱引用Bitmap,內存夠的情況Bitmap不會被回收,當緩存數大於阈值,會清除最早放入緩存的
     */
    private HashMap> mCacheMap = new LinkedHashMap>() {
        @Override
        protected boolean removeEldestEntry(Entry eldest) {
            return size() > MAX_CACHE_COUNT;
        }
    };

    /**
     * 添加圖片到緩存中
     * */
    public void put(String id,Bitmap bitmap) {
        mCacheMap.put(id, new SoftReference<>(bitmap));
    }

    /**
     * 取出緩存中的圖片
     * */
    public Bitmap get(String id,Bitmap bitmap) {
       if(!mCacheMap.containsKey(id))return null;
        SoftReference ref = mCacheMap.get(id);
        return ref.get();
    }

    /**
     * 清除所有緩存
     * */
    public void clear() {
        try{
            for (Map.Entry>entry : mCacheMap.entrySet()) {
                SoftReference sr = entry.getValue();
                if(null != sr) {
                    Bitmap bitmap = sr.get();
                    if(null != bitmap) {
                        bitmap.recycle();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

而Google老東家並不建議這樣做,官方最佳實踐中給我們推薦了關於緩存的兩個API:
LruCache(內存緩存) 和 DiskLruCache(磁盤緩存)
LruCache是以強引用(直接引用)的方式引用外界的緩存對象的,不會被GC回收,
SoftReference引用,當系統內存不足的時候回隨GC回收
還有個WeakRefreence,隨時都可能會被系統回收…
如果你對這個很有興趣,可移步到官方的最佳實踐:Caching Bitmaps

磁盤緩存

每個應用的內存都是有限的,如果是大批量的圖片,不可能全部塞到內存中,
我們可以考慮把圖片保存到磁盤中,老舊的做法是在SD上創建一個文件夾,
然後把圖片保存到裡面,網上很容易就能找到代碼,這裡不討論這個,本節
我們用上面Google推薦的DiskLruCache來做磁盤緩存

2)同步加載與異步加載

同步和異步的概念,相信很多人都了然於心了,簡單點說:
同步:發出加載圖片的調用後,要直到完成加載才能夠做其他操作
異步:發出加載圖片的調用後,想干嘛就干嘛,不用等他加載完才能去做其他事。

3)圖片加載流程圖

\

4)圖片OOM,壓縮之類關於Bitmap的概念

以前在入門教程那裡寫過就不再重復了:

Android基礎入門教程——8.2.1 Bitmap(位圖)詳解
Android基礎入門教程——8.2.2 Bitmap引起的OOM問題

也可以移步到我的好基友——基神的個人博客查看,解釋得更加詳細:

Android Bitmap 優化(1) - 圖片壓縮
Android Bitmap 優化(2) - 圖片緩存


3.簡單的圖片加載框架流程圖

盡管代碼不算復雜,覺得還是有必要畫個流程圖幫助大家理解一下~

\


4.手撕代碼時間

PS:思前想後,還是把貼代碼還是放最後吧,只做下代碼折疊截圖簡單
解釋一波,具體自己看代碼,

\

①DiskLruCache.java

這個是Google提供的,直接下這個類
https://android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/libcore/io/DiskLruCache.java
然後加到你的工程裡,自己改下包名就能用了~

②圖片壓縮類:SisterCompress.java

\

③網絡加載協助類:NetworkHelper.java

\

④內存緩存協助類:MemoryCacheHelper.java

\

⑤磁盤緩存協助類:DiskCacheHelper.java

\

⑥尺寸轉換類:SizeUtils.java

PS: 設置ImageView大小用到

\

⑦加載結果類:LoaderResult.java

PS:就是異步加載圖片後傳給Handler的數據集合

\

⑧圖片加載邏輯控制類:SisterLoader.java

\

⑨調用圖片加載框架:MainActivity.java

private SisterLoader mLoader;
mLoader = SisterLoader.getInstance(MainActivity.this);
mLoader.bindBitmap(data.get(curPos).getUrl(),showImg,400,400);

5.運行效果圖

被人趕出辦公室了,效果圖其實和前面的效果是一樣的,不過加入了我們的
圖片加載框架,加載過的圖片會緩存起來,下次加載同樣的圖片就能
很快顯示,具體效果還可以看打印的Log~(明天補下圖)


6.代碼下載

本節代碼是切換到新的分支下編寫的:sisterloader
代碼編寫完後,本地直接merge到develop分支,最後推送到Github的!
命令和上節的一樣!

https://github.com/coder-pig/DrySister/tree/develop

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved