Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 磁盤緩存 DiskLruCache

Android 磁盤緩存 DiskLruCache

編輯:關於Android編程

上一篇講了內存緩存,這一篇就緊接著講一下磁盤緩存DiskLruCache.

官方文檔:

https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html#memory-cache

內存緩存雖然對於快速訪問最近浏覽過的圖片很有用,但是我們不能總想著將圖片全部緩存在內存。因為內存的大小畢竟是有限制的,像GridView這樣的具有較大數據集的組件可以輕松地填充內存緩存。還有就是我們的應用程序可能會被其他任務(如電話呼叫)中斷,而在後台可能會被終止並且內存緩存被破壞。一旦用戶恢復,我們的應用程序必須再次加載每個圖像。在這些情況下,可以使用磁盤緩存來持久存儲圖片,這樣如果應用內存釋放了,再次打開用的時候,就不用去網絡上加載了,直接去外部存儲設備獲取,這樣節約時間,也節省流量。當然,從磁盤獲取圖片比從內存加載更慢,應該在後台線程中完成,因為磁盤讀取時間可能是不可預測的。

注意:如果更頻繁地訪問緩存的圖像,例如在圖像庫應用程序中,ContentProvider可能更適合存儲緩存的圖像。

內存緩存google提供了LruCache,而磁盤緩存,google推薦使用DiskLruCache,由於DiskLruCache並不是由Google官方編寫的,所以這個類並沒有被包含在Android API當中,我們需要將這個類從網上下載下來,然後手動添加到項目當中。DiskLruCache的源碼在Google Source上,地址如下:

https://android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/libcore/io/DiskLruCache.java

我上傳的是是從googleSource直接拷貝下來的,有兩個地方需要修改一下

1.注釋掉System.logW...相關的代碼。2.將StrictLineReader替換為BufferedInputStream

修改後的就是guolin博主上傳的。

下載好了源碼之後,只需要在項目中新建一個libcore.io包,然後將DiskLruCache.Java文件復制到這個包中即可

關於DiskLruCache的源碼分析,可以參考:

http://blog.csdn.net/lmj623565791/article/details/47251585

下面就寫個demo,來演示一下如何使用DiskLruCache:

demo做的事情就是去網絡上加載一張圖片,第一次加載,磁盤中肯定是沒有緩存的,所以從網絡上取回來後,再存入磁盤,下次加載該圖片則直接從磁盤獲取。

先分步解釋一下代碼,最後再貼全部代碼:

 

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.imageView);
        // Initialize disk cache on background thread
        File cacheDir = getDiskCacheDir(this, DISK_CACHE_SUBDIR);
        Log.d(TAG,"diskcacheDir="+cacheDir.getAbsolutePath());

        new InitDiskCacheTask().execute(cacheDir);
    }

 /**
     * 初始化DiskLruCache
     */
    class InitDiskCacheTask extends AsyncTask {
        @Override
        protected Void doInBackground(File... params) {
            synchronized (mDiskCacheLock) {
                File cacheDir = params[0];
                try {
                    mDiskLruCache = DiskLruCache.open(cacheDir,getAppVersion(),1,DISK_CACHE_SIZE);
                    mDiskCacheStarting = false; // Finished initialization
                    mDiskCacheLock.notifyAll(); // Wake any waiting threads
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }
第一步是另起線程去初始化DiskLruCache,

 

磁盤緩存首先確定好存儲的路徑:

 // Creates a unique subdirectory of the designated app cache directory. Tries to use external
    // but if not mounted, falls back on internal storage.
    private   File getDiskCacheDir(Context context, String uniqueName) {
        // Check if media is mounted or storage is built-in, if so, try and use external cache dir
        // otherwise use internal cache dir
        final String cachePath =
                Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
                        !isExternalStorageRemovable() ? getExternalCacheDir().getPath() :
                        context.getCacheDir().getPath();

        return new File(cachePath + File.separator + uniqueName);
    }

DiskLruCache並沒有限制數據的緩存位置,可以自由地進行設定,但是通常情況下多數應用程序都會將緩存的位置選擇為/storage/sdcard/Android/data//cache/這個目錄下,如:

 

\

cj.com.disklrucache就是應用的包名,disccache就是自己設置的緩存子目錄。

選擇在這個位置有兩點好處:第一,這是存儲在SD卡上的,因此即使緩存再多的數據也不會對手機的內置存儲空間有任何影響,只要SD卡空間足夠就行。第二,這個路徑被Android系統認定為應用程序的緩存路徑,當程序被卸載的時候,這裡的數據也會一起被清除掉,這樣就不會出現刪除程序之後手機上還有很多殘留數據的問題。

當然如果沒有sd卡的話,就存儲在/cache/目錄下。

 

mDiskLruCache = DiskLruCache.open(cacheDir,getAppVersion(),1,DISK_CACHE_SIZE);
創建DiskLruCache需要四個參數,分別是緩存路徑,應用版本,每個key對應的值的個數(這裡一般寫一個),緩存最大容量(單位字節)。

 

初始化完DiskLruCache,會在緩存目錄創建一個文件名為journal文件,journal文件是DiskLruCache的一個日志文件,程序對緩存數據的操作記錄都存放在這個文件中,那就看一下這個文件的內容:

\

首先看前五行:

 

  • 第一行固定以READ前綴開始的,字符串libcore.io.DiskLruCache
  • 第二行DiskLruCache的版本號,源碼中為常量1
  • 第三行為你的app的版本號,自己傳入指定的
  • 第四行指每個key對應幾個文件,一般為1自己傳入指定的
  • 第五行,空行

 

這就是文件頭。

第6開始就是你緩存數據的記錄了,這裡我只操作一張圖片,所以只有關於一個key記錄

以DIRTY前綴開始的,後面緊跟著緩存圖片的key.我這裡用hashcode值作為key了。

以CLEAN前綴開始的,表示上面key值代表的圖片緩存成成功了,後面緊跟的數字的就是緩存的字節大小.對比一下(看上面兩張圖片大小差不多326656 , 326700)

以READ前綴開始的,表示從緩存中獲取了一次該key對應的緩存數據

以REMOVE前綴開始的,表示刪除了該key對應的緩存數據

接著往下看,

\

第一次點擊load button去網絡上加載圖片:

 

public void click(View v){
        Log.d(TAG,"click");
        switch (v.getId()){
            case R.id.button:
                BitmapWorkerTask task = new BitmapWorkerTask(imageView);
                task.execute(IMAGE_URL);
                break;
            case R.id.delete_btn:
                try {
                    mDiskLruCache.remove(String.valueOf(IMAGE_URL.hashCode()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            default:
                break;
        }


    }

網絡請求操作放在子線程去做:

 

 

class BitmapWorkerTask extends AsyncTask {
        private final WeakReference imageViewReference;

        public BitmapWorkerTask(ImageView imageView) {
            // Use a WeakReference to ensure the ImageView can be garbage collected
            imageViewReference = new WeakReference(imageView);
        }
        // Decode image in background.
        @Override
        protected Bitmap doInBackground(String... params) {
            Log.d(TAG,"path="+params[0]);
            String key = String.valueOf(params[0].hashCode());
            // Check disk cache in background thread
            Bitmap bitmap = getBitmapFromDiskCache(key);
            if (bitmap == null) {
                Log.d(TAG,"Not found in disk cache");
                //去網絡下載
                bitmap = downLoadImage(params[0]);
                if(bitmap != null){
                    Log.d(TAG,"downLoadImage success");
                    /**
                     * 將改圖片存入disk cache
                     */
                    if(addBitmapToCache(key,bitmap)){
                        Log.d(TAG,"add to disk cache success");
                    }else{
                        Log.d(TAG,"add to disk cache failure");
                    }
                    return bitmap;
                }
                Log.d(TAG,"downLoadImage failure");
                return null;
            }
            Log.d(TAG,"found in disk cache");
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            Log.d(TAG,"onPostExecute bitmap="+bitmap);
            if (imageViewReference != null && bitmap != null) {
                final ImageView imageView = imageViewReference.get();
                if (imageView != null) {
                    imageView.setImageBitmap(bitmap);
                }
            }
        }
    }

下載之前首先去看緩存裡面有木有:

 

 

/**
     *
     * @param key
     * @return
     */
    public Bitmap getBitmapFromDiskCache(String key) {
        Log.d(TAG,"getBitmapFromDiskCache");
        synchronized (mDiskCacheLock) {
            // Wait while disk cache is started from background thread
            while (mDiskCacheStarting) {
                try {
                    mDiskCacheLock.wait();
                } catch (InterruptedException e) {}
            }
            if (mDiskLruCache != null) {
                try {
                    DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key);
                    Log.d(TAG,"getBitmapFromDiskCache  snapshot="+snapshot);
                 //   if(snapshot != null){
                //        InputStream inputStream = snapshot.getInputStream(0);
                //        Log.d(TAG,"getBitmapFromDiskCache  inputStream="+inputStream);
                //    }
                    return snapshot != null ? decodeStream(snapshot.getInputStream(0)):null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

獲取緩存的圖片,與內存緩存相比過程稍微復雜點,中間使用了DiskLruCache.Snapshot對象,然後Snapshot獲取不是圖片,而是輸入流,所以還需解碼成圖片。參數傳入0,與之前一個key對應一個值,是對應的。

 

第一次請求圖片,緩存沒有,所以要去下載:

 

 /**
     *
     * @param path
     * @return
     */
    private Bitmap downLoadImage(String path){
        Log.d(TAG,"downLoadImage");
        HttpURLConnection conn = null;
        try {
            conn = createConnection(path);
            int redirectCount = 0;//重定向的次數
            //>=300重定向相關的
            while (conn.getResponseCode() / 100 == 3 && redirectCount < MAX_REDIRECT_COUNT) {
                conn = createConnection(conn.getHeaderField("Location"));
                redirectCount++;
            }

            return decodeStream(conn.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();

        }finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        return null;
    }

 /**
     *
     * @param url
     * @return
     * @throws IOException
     */
    protected HttpURLConnection createConnection(String url) throws IOException {
        String encode = Uri.encode(url, ALLOWED_URI_CHARS);//
        Log.d(TAG,"encodeURL=="+encode);
        URL u = new URL(encode);
        HttpURLConnection conn = (HttpURLConnection) u.openConnection();
        conn.setConnectTimeout(DEFAULT_HTTP_CONNECT_TIMEOUT);//設置連接主機超時(單位:毫秒)
        conn.setReadTimeout(DEFAULT_HTTP_READ_TIMEOUT);//設置從主機讀取數據超時(單位:毫秒)
        return conn;
    }

這裡就是簡單使用HttpUrlConnection去下載了,這裡添加有關重定向的處理,這裡下載圖片就不多解釋了

 

下載完圖片後,需要將圖片存入disk

 

/**
     *
     * @param key
     * @param bitmap
     */
    public boolean addBitmapToCache(String key, Bitmap bitmap) {
        Log.d(TAG,"addInputStreamToCache");
        DiskLruCache.Editor editor = null;
        BufferedOutputStream out = null;
        BufferedInputStream in = null;
        synchronized (mDiskCacheLock) {
            try {
                InputStream inputStream = Bitmap2IS(bitmap);
                editor = mDiskLruCache.edit(key);
                OutputStream outputStream = editor.newOutputStream(0);
                in = new BufferedInputStream(inputStream,1024);
                out = new BufferedOutputStream(outputStream,1024);
                int b;
                while ((b = in.read())!=-1){
                    out.write(b);
                }
                editor.commit();
                mDiskLruCache.flush();
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }finally {
                try {
                    if (out != null) {
                        out.close();
                    }
                    if (in != null) {
                        in.close();
                    }
                } catch (final IOException e) {
                    e.printStackTrace();
                }

            }
        }

    }

DiskLruCache存數據是使用DiskLruCache.Editor,比起內存緩存還是稍微復雜點,Editor記得要執行commit()函數

 

處理的步驟就這些,

下面是全部代碼:

 

package cj.com.disklrucache;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;

import static android.os.Environment.isExternalStorageRemovable;

public class MainActivity extends AppCompatActivity {
    private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB
    private static final String DISK_CACHE_SUBDIR = "disccache";
    private static final String TAG = "disklrucache";
    private static final String IMAGE_URL = "http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg";
    private static final int MAX_REDIRECT_COUNT = 5;
    private static final String ALLOWED_URI_CHARS = "@#&=*+-_.,:!?()/~'%";
    private static final int DEFAULT_HTTP_CONNECT_TIMEOUT = 5 * 1000; // milliseconds
    private static final int DEFAULT_HTTP_READ_TIMEOUT = 20 * 1000; // milliseconds

    private final Object mDiskCacheLock = new Object();

    private DiskLruCache mDiskLruCache;
    private boolean mDiskCacheStarting = true;

    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.imageView);
        // Initialize disk cache on background thread
        File cacheDir = getDiskCacheDir(this, DISK_CACHE_SUBDIR);
        Log.d(TAG,"diskcacheDir="+cacheDir.getAbsolutePath());

        new InitDiskCacheTask().execute(cacheDir);
    }

    public void click(View v){
        Log.d(TAG,"click");
        switch (v.getId()){
            case R.id.button:
                BitmapWorkerTask task = new BitmapWorkerTask(imageView);
                task.execute(IMAGE_URL);
                break;
            case R.id.delete_btn:
                try {
                    mDiskLruCache.remove(String.valueOf(IMAGE_URL.hashCode()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            default:
                break;
        }


    }

    /**
     *
     * @param path
     * @return
     */
    private Bitmap downLoadImage(String path){
        Log.d(TAG,"downLoadImage");
        HttpURLConnection conn = null;
        try {
            conn = createConnection(path);
            int redirectCount = 0;//重定向的次數
            //>=300重定向相關的
            while (conn.getResponseCode() / 100 == 3 && redirectCount < MAX_REDIRECT_COUNT) {
                conn = createConnection(conn.getHeaderField("Location"));
                redirectCount++;
            }

            return decodeStream(conn.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();

        }finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        return null;
    }

    /**
     *
     * @param bm
     * @return
     */
    private InputStream  Bitmap2IS(Bitmap bm){
        Log.d(TAG,"Bitmap2IS");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        InputStream sbs = new ByteArrayInputStream(baos.toByteArray());
        return sbs;
    }
    /**
     *
     * @param url
     * @return
     * @throws IOException
     */
    protected HttpURLConnection createConnection(String url) throws IOException {
        String encode = Uri.encode(url, ALLOWED_URI_CHARS);//
        Log.d(TAG,"encodeURL=="+encode);
        URL u = new URL(encode);
        HttpURLConnection conn = (HttpURLConnection) u.openConnection();
        conn.setConnectTimeout(DEFAULT_HTTP_CONNECT_TIMEOUT);//設置連接主機超時(單位:毫秒)
        conn.setReadTimeout(DEFAULT_HTTP_READ_TIMEOUT);//設置從主機讀取數據超時(單位:毫秒)
        return conn;
    }

    /**
     *
     * @param key
     * @param bitmap
     */
    public boolean addBitmapToCache(String key, Bitmap bitmap) {
        Log.d(TAG,"addInputStreamToCache");
        DiskLruCache.Editor editor = null;
        BufferedOutputStream out = null;
        BufferedInputStream in = null;
        synchronized (mDiskCacheLock) {
            try {
                InputStream inputStream = Bitmap2IS(bitmap);
                editor = mDiskLruCache.edit(key);
                OutputStream outputStream = editor.newOutputStream(0);
                in = new BufferedInputStream(inputStream,1024);
                out = new BufferedOutputStream(outputStream,1024);
                int b;
                while ((b = in.read())!=-1){
                    out.write(b);
                }
                editor.commit();
                mDiskLruCache.flush();
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }finally {
                try {
                    if (out != null) {
                        out.close();
                    }
                    if (in != null) {
                        in.close();
                    }
                } catch (final IOException e) {
                    e.printStackTrace();
                }

            }
        }

    }

    /**
     *
     * @param key
     * @return
     */
    public Bitmap getBitmapFromDiskCache(String key) {
        Log.d(TAG,"getBitmapFromDiskCache");
        synchronized (mDiskCacheLock) {
            // Wait while disk cache is started from background thread
            while (mDiskCacheStarting) {
                try {
                    mDiskCacheLock.wait();
                } catch (InterruptedException e) {}
            }
            if (mDiskLruCache != null) {
                try {
                    DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key);
                    Log.d(TAG,"getBitmapFromDiskCache  snapshot="+snapshot);
                    if(snapshot != null){
                        InputStream inputStream = snapshot.getInputStream(0);
                        Log.d(TAG,"getBitmapFromDiskCache  inputStream="+inputStream);
                    }
                    return snapshot != null ? decodeStream(snapshot.getInputStream(0)):null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     *
     * @param inputStream
     * @return
     */
    private Bitmap decodeStream(InputStream inputStream){
        return inputStream != null ? BitmapFactory.decodeStream(inputStream):null;
        //BitmapFactory.decodeStream(InputStream is, Rect outPadding, BitmapFactory.Options opts)
    }

    // Creates a unique subdirectory of the designated app cache directory. Tries to use external
    // but if not mounted, falls back on internal storage.
    private   File getDiskCacheDir(Context context, String uniqueName) {
        // Check if media is mounted or storage is built-in, if so, try and use external cache dir
        // otherwise use internal cache dir
        final String cachePath =
                Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
                        !isExternalStorageRemovable() ? getExternalCacheDir().getPath() :
                        context.getCacheDir().getPath();

        return new File(cachePath + File.separator + uniqueName);
    }

    private int getAppVersion(){
        try {
            PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0);
            return info.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return 1;
    }

    /**
     * 初始化DiskLruCache
     */
    class InitDiskCacheTask extends AsyncTask {
        @Override
        protected Void doInBackground(File... params) {
            synchronized (mDiskCacheLock) {
                File cacheDir = params[0];
                try {
                    mDiskLruCache = DiskLruCache.open(cacheDir,getAppVersion(),1,DISK_CACHE_SIZE);
                    mDiskCacheStarting = false; // Finished initialization
                    mDiskCacheLock.notifyAll(); // Wake any waiting threads
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }

    /**
     *
     */
    class BitmapWorkerTask extends AsyncTask {
        private final WeakReference imageViewReference;

        public BitmapWorkerTask(ImageView imageView) {
            // Use a WeakReference to ensure the ImageView can be garbage collected
            imageViewReference = new WeakReference(imageView);
        }
        // Decode image in background.
        @Override
        protected Bitmap doInBackground(String... params) {
            Log.d(TAG,"path="+params[0]);
            String key = String.valueOf(params[0].hashCode());
            // Check disk cache in background thread
            Bitmap bitmap = getBitmapFromDiskCache(key);
            if (bitmap == null) {
                Log.d(TAG,"Not found in disk cache");
                //去網絡下載
                bitmap = downLoadImage(params[0]);
                if(bitmap != null){
                    Log.d(TAG,"downLoadImage success");
                    /**
                     * 將改圖片存入disk cache
                     */
                    if(addBitmapToCache(key,bitmap)){
                        Log.d(TAG,"add to disk cache success");
                    }else{
                        Log.d(TAG,"add to disk cache failure");
                    }
                    return bitmap;
                }
                Log.d(TAG,"downLoadImage failure");
                return null;
            }
            Log.d(TAG,"found in disk cache");
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            Log.d(TAG,"onPostExecute bitmap="+bitmap);
            if (imageViewReference != null && bitmap != null) {
                final ImageView imageView = imageViewReference.get();
                if (imageView != null) {
                    imageView.setImageBitmap(bitmap);
                }
            }
        }
    }

}

看一下log:

 

 

D/disklrucache: click
D/disklrucache: path=http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg
D/disklrucache: getBitmapFromDiskCache
D/disklrucache: getBitmapFromDiskCache  snapshot=null
D/disklrucache: Not found in disk cache
D/disklrucache: downLoadImage
D/disklrucache: encodeURL==http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg
D/disklrucache: encodeURL==https://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg
D/disklrucache: downLoadImage success
D/disklrucache: addInputStreamToCache
D/disklrucache: Bitmap2IS
D/disklrucache: add to disk cache success
D/disklrucache: onPostExecute bitmap=android.graphics.Bitmap@3396b564
D/disklrucache: click
D/disklrucache: path=http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg
D/disklrucache: getBitmapFromDiskCache
D/disklrucache: getBitmapFromDiskCache  snapshot=cj.com.disklrucache.DiskLruCache$Snapshot@1f9bd793
D/disklrucache: getBitmapFromDiskCache  inputStream=java.io.FileInputStream@3fbbc3d0
D/disklrucache: found in disk cache
D/disklrucache: onPostExecute bitmap=android.graphics.Bitmap@1b7befc9
D/disklrucache: click
D/disklrucache: click
D/disklrucache: path=http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg
D/disklrucache: getBitmapFromDiskCache
D/disklrucache: getBitmapFromDiskCache  snapshot=null
D/disklrucache: Not found in disk cache
D/disklrucache: downLoadImage
D/disklrucache: encodeURL==http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg
D/disklrucache: encodeURL==https://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg
D/disklrucache: downLoadImage success
D/disklrucache: addInputStreamToCache
D/disklrucache: Bitmap2IS
D/disklrucache: add to disk cache success
D/disklrucache: onPostExecute bitmap=android.graphics.Bitmap@354a86ce
Application terminated.

具體動作就是,先點擊load button 這時會去網上下載,再次點擊load button 就會去緩存裡去獲取,然後點擊delete button 刪除了緩存,最後再點load button 又會去網上下載。

 

日志記錄(上面那張圖記錄的)。

關於DiskLruCache還有一些其他API:

 

1.size()

這個方法會返回當前緩存路徑下所有緩存數據的總字節數,以byte為單位,如果應用程序中需要在界面上顯示當前緩存數據的總大小,就可以通過調用這個方法計算出來。

 

2.flush()

這個方法用於將內存中的操作記錄同步到日志文件(也就是journal文件)當中。這個方法非常重要,因為DiskLruCache能夠正常工作的前提就是要依賴於journal文件中的內容。並不是每次寫入緩存都要調用一次flush()方法的,頻繁地調用並不會帶來任何好處,只會額外增加同步journal文件的時間。比較標准的做法就是在Activity的onPause()方法中去調用一次flush()方法就可以了。

3.close()

這個方法用於將DiskLruCache關閉掉,是和open()方法對應的一個方法。關閉掉了之後就不能再調用DiskLruCache中任何操作緩存數據的方法,通常只應該在Activity的onDestroy()方法中去調用close()方法。

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