1. 程式人生 > >簡述安卓中的三級快取機制

簡述安卓中的三級快取機制

Android應用中聯網載入並顯示圖片時,為了使用者體驗和節省流量,一定用到圖片的快取

關於三級快取的理解可以分為:

  1. 記憶體快取(物理空間的快取)
  2. 本地快取(java物件的快取)
  3. 網路快取

首先為大家介紹一個現在比較成熟應用也比較廣泛的第三方開源的工具類 xUtils系列之BitmapUtils

接下來我們將通過自己的程式碼為大家分析BitmapUtils實現圖片載入等一系列工作的原理

  • 第一步:建立三個類NetCacheUtils(用於網路快取)
    LocalCacheUtils(用於本地快取)
    MemoryCacheUtils(用於記憶體快取)
  • 第二步:建立MyBitmapUtils類,用於處理使用者載入圖片的請求

建立本地快取類LocalCacheUtils:

public class LocalCacheUtils {
    public static final String CACHE_PATH = Environment
            .getExternalStorageDirectory().getAbsolutePath() + "/zhwh";



    public Bitmap getBitmap(String url) {
        String fiaeneme;
        try
{ fiaeneme = MD5Encoder.encode(url); File file = new File(CACHE_PATH, fiaeneme); if(file.exists()){ Bitmap bitmap=BitmapFactory.decodeStream(new FileInputStream(file)); System.out.println("內地快取執行。。。。。。"); return bitmap; } } catch
(Exception e) { e.printStackTrace(); } return null; } /** * * @param @param url * @param @param bitmap * @return void */ public void setBitmap(String url, Bitmap bitmap) { try { String fiaeneme = MD5Encoder.encode(url); File file = new File(CACHE_PATH, fiaeneme); File parentFile = file.getParentFile(); if (!parentFile.exists()) {// 如果資料夾不存在, 建立資料夾 parentFile.mkdirs(); } // 將圖片儲存在本地 bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(file)); } catch (Exception e) { e.printStackTrace(); } } }

對LocalCacheUtils的解釋說明:

主要的兩個方法:setBitmap(String url, Bitmap bitmap)和getBitmap(String url)

  1. setBitmap(String url, Bitmap
    bitmap):以經過處理後的url為檔名在記憶體中建立一個檔案,然後將傳入的Bitmap 物件寫入這個檔案當中去
  2. getBitmap(String url) :以相同的方式處理url作為檔名在記憶體中讀取檔案中的BitMap物件並返回

建立記憶體快取類MemoryCacheUtils:

public class MemoryCacheUtils {
    private LruCache<String, Bitmap> mMemoryCache;

    public MemoryCacheUtils() {
        long maxMemory = Runtime.getRuntime().maxMemory() / 8;// 模擬器預設是16M
        mMemoryCache = new LruCache<String, Bitmap>((int) maxMemory) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                int byteCount = value.getRowBytes() * value.getHeight();// 獲取圖片佔用記憶體大小
                return byteCount;
            }
        };
    }

    public Bitmap getBitmap(String url) {
        return mMemoryCache.get(url);
    }

    public void setBitmap(String url, Bitmap bitmap) {
        mMemoryCache.put(url, bitmap);
    }
}

關於LruCache的說明:LruCache是android提供的一個快取工具類,其演算法是最近最少使用演算法。它把最近使用的物件用“強引用”儲存在LinkedHashMap中,並且把最近最少使用的物件在快取值達到預設定值之前就從記憶體中移除。關於LruCache的詳細說明

建立網路快取類:NetCacheUtils

public class NetCacheUtils {
    LocalCacheUtils utils1;
    MemoryCacheUtils utils2;

    public NetCacheUtils(LocalCacheUtils utils1, MemoryCacheUtils utils2) {
        this.utils1 = utils1;
        this.utils2 = utils2;
    }

    public void getBitmapFromNet(ImageView iv, String url) {
        new BitmapTask().execute(iv, url);
    }

    /**
     * 非同步下載
     * 
     * @author 直到世界盡頭
     * 
     */
    class BitmapTask extends AsyncTask<Object, Void, Bitmap> {

        private ImageView iv;
        private String url;

        /**
         * 子執行緒進行
         * 
         * @param @param arg0
         * @param @return
         * @return Bitmap 返回下載得到的資料結果
         */
        @Override
        protected Bitmap doInBackground(Object... parms) {
            iv = (ImageView) parms[0];
            url = (String) parms[1];
            iv.setTag(url);// 將url和imageview繫結
            return downloadbitmap(url);
        }

        @Override
        protected void onProgressUpdate(Void... values) {

            super.onProgressUpdate(values);
        }

        /**
         * 下載完成之後執行
         */
        @Override
        protected void onPostExecute(Bitmap result) {
            super.onPostExecute(result);

            String bindurl = (String) iv.getTag();
            if (bindurl.equals(url)) {
                iv.setImageBitmap(result);
            }

            // 載入到本地記憶體
            utils1.setBitmap(url, result);
            // 載入到快取記憶體
            utils2.setBitmap(url, result);
            System.out.println("網路獲取圖片。。。。");
        }
    }

    private Bitmap downloadbitmap(String url) {
        HttpURLConnection connection = null;
        try {
            URL u = new URL(url);
            connection = (HttpURLConnection) u.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            connection.connect();
            if (connection.getResponseCode() == 200) {
                InputStream is = connection.getInputStream();
                // 圖片壓縮處理
                BitmapFactory.Options option = new BitmapFactory.Options();
                option.inSampleSize = 2;// 寬高都壓縮為原來的二分之一, 此引數需要根據圖片要展示的大小來確定
                option.inPreferredConfig = Bitmap.Config.RGB_565;// 設定圖片格式

                Bitmap bitmap = BitmapFactory.decodeStream(is, null,option);
                return bitmap;
            }

        } catch (Exception e) {

            e.printStackTrace();
        } finally {
            connection.disconnect();
        }

        return null;
    }
}

說明:關於這個類中用到的一步載入可見另一篇部落格非同步載入詳解

最後建立MyBitmapUtils類用於協調呼叫前面的三個快取類:

public class MyBitmapUtils {
    NetCacheUtils netcacheutils;
    LocalCacheUtils localcacheutils;
    MemoryCacheUtils memorycacheutils;

    public MyBitmapUtils() {
        localcacheutils = new LocalCacheUtils();
        memorycacheutils = new MemoryCacheUtils();
        this.netcacheutils = new NetCacheUtils(localcacheutils,
                memorycacheutils);
    }

    /**
     * 三級快取
     * 
     * @param @param iv
     * @param @param url
     * @return void
     */
    public void Display(ImageView iv, String url) {
        Bitmap map;
        //記憶體快取
        map = memorycacheutils.getBitmap(url);
        if (map != null) {
            iv.setImageBitmap(map);
            return;
        }

        // 本地快取
        map = localcacheutils.getBitmap(url);
        if (map != null) {
            memorycacheutils.setBitmap(url, map);
            iv.setImageBitmap(map);
            return;
        }

        // 網路快取
        netcacheutils.getBitmapFromNet(iv, url);
    }
}

三級快取呼叫流程

相關推薦

簡述三級快取機制

Android應用中聯網載入並顯示圖片時,為了使用者體驗和節省流量,一定用到圖片的快取 關於三級快取的理解可以分為: 記憶體快取(物理空間的快取) 本地快取(java物件的快取) 網路快取 首先為大家介紹一個現在比較成熟應用也比較廣泛的第

圖片三級快取策略與實現

前言: 這裡說的三級快取,分別指的是:記憶體快取、檔案快取和網路這三個層面。 一般來說,我們首次載入圖片,記憶體和檔案是沒有快取的,這樣我們需要從網路載入,載入完成後,我們會存到記憶體和檔案中去;當再次載入圖片的時候,我們會先查詢記憶體有沒有,如果有就直接顯示記憶體中的圖片

RxJava2.0在的二級快取策略

前言 在上一篇 安卓網路資料快取策略 中,介紹了安卓中資料的快取策略,這篇將用RxJava2.0 實現 Json/Xml 資料的二級快取。 對於 RxJava2.0 不瞭解的,可以看一下這篇入門教程 從零開始的RxJava2.0教程1-4 。 彷彿有一

的訊息迴圈機制Handler及Looper詳解

我們知道安卓中的UI執行緒不是執行緒安全的,我們不能在UI執行緒中進行耗時操作,通常我們的做法是開啟一個子執行緒在子執行緒中處理耗時操作,但是安卓規定不允許在子執行緒中進行UI的更新操作,通常我們會通過Handler機制來完成該功能,即當子執行緒中耗時操作完成後,在子執行緒

關於Android開發圖片的三級快取機制

1.Android應用中聯網載入並顯示圖片時,為了使用者體驗和節省流量,一定用到圖片的快取。 2.關於三級快取的理解:記憶體快取(強引用儲存)、記憶體快取(軟引用快取)、記憶體快取(弱引用快取)、檔案快取(就是將圖片儲存為本地檔案),由此組成三級快取。 3.關於JAVA中的

遮罩圖片的處理

reference south res rac req hat 代碼 cep flag 安卓開發中必不可少的就是各種圖片的圓角,遮罩等等。 曾經我都是用shape處理的。發現背景圖的圓角要設置成和界面父元素背景一樣才幹看不出現紕漏。 當遇到背景多變的情況,比方listv

解決單個dex方法數超過65535的方法

ati oid 超過 sta get ble text enabled 方法 1、百度下載 60K-methods.jar包,復制至libs文件夾中,添加到gradle中 2、在build.gradle中的defaultConfig{}下添加 multiDexEnable

Bitmap的處理

呼叫安卓手機系統照相機進行拍照 系統照相機得到的相片解析度太大,如果不處理直接使用就會導致OutOfMemery異常,我採用的是下面這段程式碼:// 計算圖片的縮放值public static int calculateInSampleSize(BitmapFactory.Options opt

管理Activity

安卓中一般在BaseActivity 管理所有的Activity 因為所有的Activity 繼承自BaseActivity 步驟: 1:在BaseActivity New 一個ArrayList 儲存Activity private List<Activity> allA

探索java與json物件與json字串之間的關係

  前段時間一直在跟json資料打交道,從一開始的什麼都不懂,到現在整合了許多知識的懵懂,還是收穫了不少對於json格式資料新的看法和安卓資料傳輸的理解。   首先,json資料的格式是什麼樣的呢?我們來定義一個字串型別的json資料。  String json

遇見的一些問題

Android-studio程式碼中遇到的一些問題-----持續更新記錄 1、安卓studio gradle正常編譯執行時找不到library包 圖片描述 解決辦法 將library專案下的build.gradle->buildTypes{

Cordova - 徹底搞定的微信支付插件!

以及 andro 發現 bug 輸入參數 為我 開始 如何 工具 你看到這個標題肯定會驚訝,一個Cordova的微信支付插件,有這麽誇張嗎?信不信由你,我相信,最終你會回來看這篇文章的! 一,不要使用的微信支付插件:https://github.com/xu-li/cord

Cordova - 徹底搞定的微信支付外掛!

Cordova:8.0.0 Android studio:3.2.1 你看到這個標題肯定會驚訝,一個Cordova的微信支付外掛,有這麼誇張嗎? 一,不要使用的微信支付外掛:https://github.com/xu-li/cordova-plugin-wechat  上面的外掛,是目前大家

關於的Handler

Handler是用來執行緒間傳遞資料,在主執行緒將Handler例項化,子執行緒《工作執行緒,執行較長的耗時業務》可以通過Handler傳送資料到主執行緒,當Looper輪詢到Message Queue時,將訊息交給 Handler進行處理,通過回撥handleMessage(Message m

SpringBoot(七) SpringBoot快取機制

隨著時間的積累,應用的使用使用者不斷增加,資料規模也越來越大,往往資料庫查詢操作會成為影響使用者使用體驗的瓶頸,此時使用快取往往是解決這一問題非常好的手段之一。Spring 3開始提供了強大的基於註解的快取支援,可以通過註解配置方式低侵入的給原有Spring應用增加快取功能,提高資料訪問效能。 Spring

如何使用Sensor simulator 在模擬器上進行感測器開發

大家好啊,這是本人的第一篇部落格,最近在搞安卓的感測器開發,在這篇文章裡我詳述了基於SensorSimulator的感測器開發步驟。使用SensorSimulator可以在沒有手機的情況下在電腦上模擬手機的姿態,來測試比如像用到方向感測器一類的程式。希望對大家有所幫助。 0.啟動eclipse,

資料庫運用---做個便籤app

前言:這個app其實很早之前就做完了,但當時沒有積累,大二剛開了Java課對安卓有了一些新認識於是前幾天就把這個app重做了一遍,總結下來(文章最後有GitHub地址,但建議還是先看一下部落格的思路) 效果如圖: 總體就是運用資料庫裡的修改,儲存,還有recycl

藍芽擴音HFP的一些分析

最近看了一些大牛的部落格,無不提到了技術分享的重要性,的確,分享自己的知識不僅僅是與他人討論並相互提高的過程,更是對自己知識的梳理。希望自己能以此為契機,形成周期性部落格分享的習慣。 文章標題為HFP的一些分析,HFP(Hand Free Profile)主要定義了安卓中與

開發客串下美工用三個gif 圖實現的走馬燈效果

安卓開發客串下美工用三個gif 圖實現安卓中的走馬燈效果   最終效果是這個樣子的          ??????????????? 這個不像跑馬燈,到像是受驚的野馬亂蹦 啊,呵呵,在本地快

SpringBoot(七) SpringBoot快取機制

隨著時間的積累,應用的使用使用者不斷增加,資料規模也越來越大,往往資料庫查詢操作會成為影響使用者使用體驗的瓶頸,此時使用快取往往是解決這一問題非常好的手段之一。Spring 3開始提供了強大的基於註解的快取支援,可以通過註解配置方式低侵入的給原有Spring應用增加快取功能,提高資料訪問效能。 Spring