筆記: Bitmap加載和Cache

Bitmap加載和Cache


  • BitmapOptions

decodeFile

decodeStream

decodeResource

decodeByteArray


  • BitmapFactory.Options

inSampleSize:采用率

為1時(shí):采樣后的圖片和原圖沒區(qū)別

大于1:比如等于2時(shí),采樣后的圖片寬高為原來(lái)的1/2,像素為原圖的1/4,占用的內(nèi)存大小也為原圖的1/4

一張10241024的argb8888格式圖片,每個(gè)像素大小是4bit(1bit8位,四個(gè)8就4bit),總大小為102410244=4MB,采用insamplesize為2后,總大小為512512*4=1MB

所以insampleSize大于1時(shí)才會(huì)有采樣縮放

inSampleSize同時(shí)作用于寬高,寬高大小隨采樣率的2次方遞減,1/采樣率^2

inSampleSize小于1時(shí)值等于1來(lái)處理。

官方建議按照2的指數(shù)來(lái)設(shè)置inSampleSize,如1,2,4,16...


    /*圖片壓縮采樣*/
    public Bitmap decodeSampledBitmapFromResource(Resources res, @IdRes int id, int reqWidth, int reqHeight) {
        final BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, id, opts);
        int outWidth = opts.outWidth;
        int outHeight = opts.outHeight;

        int inSampleSize = calculateInSampleSize(outWidth, outHeight, reqWidth, reqHeight);

        opts.inJustDecodeBounds = false;
        opts.inSampleSize = inSampleSize;

        return BitmapFactory.decodeResource(res, id, opts);
    }
    
        private int calculateInSampleSize(int outWidth, int outHeight, int reqWidth, int reqHeight) {

        if (reqHeight == 0 || reqWidth == 0) {
            return 1;
        }

        int inSampleSize = 1;
        if (outWidth > reqWidth || outHeight > reqHeight) {
            int w = outWidth / 2;
            int h = outHeight / 2;

            while ((w / inSampleSize) >= reqWidth && (h / inSampleSize) >= reqHeight) {
                inSampleSize *= 2;
            }
        }
        Log.d(TAG, "inSampleSize:" + inSampleSize);
        return inSampleSize;
    }


  • LruCache 內(nèi)存緩存
  • DisLruCache 存儲(chǔ)設(shè)備緩存

  • LruCache

LruCache是一個(gè)泛型類,內(nèi)部維護(hù)一個(gè)LinkedHashMap,以強(qiáng)引用的方式存儲(chǔ)外界的對(duì)象,提供了get,put方法來(lái)完成緩存對(duì)象的獲取和添加,當(dāng)緩存滿時(shí),會(huì)移除較早使用的對(duì)象并添加新對(duì)象。


  • DiskLruCache

SDK源碼中沒有,需要去安卓開發(fā)者網(wǎng)站上下載

Link

1. 創(chuàng)建:
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
            throws IOException {}

第四個(gè)參數(shù)maxSize表示總大小。當(dāng)超過(guò)指定的總大小后,會(huì)通過(guò)lru算法刪除某些內(nèi)容。

2. 添加元素

通過(guò)edit()的Editor對(duì)象,如果這個(gè)緩存正在被編輯,edit()會(huì)返回null,建議對(duì)key進(jìn)行MD5話,避免特殊字符的麻煩。

通過(guò)Editor.newOutputStream()獲得輸出流

通過(guò)Editor.commit()提交寫入操作,通過(guò)Editor.abort()來(lái)回退整個(gè)操作,之后通過(guò)DiskLruCache.flush()刷新。

3. DiskLruCache緩存查找

通過(guò)get(key)方法,返回Snapshot對(duì)象,再通過(guò)Snapshot.getInputStream()獲取輸入流,加載文件。


  • 優(yōu)化列表卡頓
  1. getView中不做耗時(shí)操作
  2. 監(jiān)聽滾動(dòng)事件,當(dāng)滾動(dòng)時(shí)不去加載圖片,僅僅當(dāng)列表停止時(shí)加載。
  3. 開啟硬件加速:在Activity清單文件節(jié)點(diǎn)加上android:hardwareAccelerated="true"
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容