Cache【硬盤緩存工具類(包含內存緩存LruCache和磁盤緩存DiskLruCache)】

版權聲明:本文爲HaiyuKing原創文章,轉載請註明出處!html

前言

內存緩存LruCache和磁盤緩存DiskLruCache的封裝類,主要用於圖片緩存。java

效果圖

代碼分析

內存緩存LruCache和磁盤緩存DiskLruCache根據實際狀況進行緩存,有時候須要二者都用到,有時候只用磁盤緩存便可。android

使用步驟

1、項目組織結構圖

注意事項:git

一、  導入類文件後須要change包名以及從新import R文件路徑github

二、  Values目錄下的文件(strings.xml、dimens.xml、colors.xml等),若是項目中存在,則複製裏面的內容,不要整個覆蓋緩存

2、導入步驟

將Cache、DiskLruCache文件複製到項目中

在AndroidManifest.xml中添加權限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.why.project.cachedemo">

    <!-- =====================Cache【硬盤緩存工具類(包含內存緩存LruCache和磁盤緩存DiskLruCache)】======================= --> <!-- 容許程序打開網絡套接字 --> <uses-permission android:name="android.permission.INTERNET"/> <!-- 容許程序訪問有關GSM網絡信息 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 容許程序訪問Wi-Fi網絡狀態信息 --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 在SD卡中建立與刪除文件權限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <!-- 容許程序讀取外部存儲文件 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <!-- 容許程序寫入外部存儲,如SD卡上寫文件 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

添加運行時權限的處理(本demo中採用的是修改targetSDKVersion=22)

3、使用方法

package com.why.project.cachedemo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import com.why.project.cachedemo.utils.cache.Cache; import java.net.URL; public class MainActivity extends AppCompatActivity { private Button btn_save; private Button btn_show; private Button btn_getsize; private Button btn_remove; private TextView tv_size; private ImageView img_show; private GetImgToSaveCacheTask getImgToSaveCacheTask;//獲取圖片並保存到緩存的異步請求類

    /**內存、磁盤緩存*/ private Cache mCache; String imgUrl = "http://img.ithome.com/newsuploadfiles/2014/12/20141223_115629_592.jpg"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /**必須在使用以前初始化*/ mCache = new Cache(this); mCache.initMemoryCache(); mCache.initDiskCache(); initViews(); initEvents(); } @Override public void onPause() { super.onPause(); //cancel方法只是將對應的AsyncTask標記爲cancel狀態,並非真正的取消線程的執行,在Java中並不能粗暴的中止線程,只能等線程執行完以後作後面的操做
        if(getImgToSaveCacheTask != null && getImgToSaveCacheTask.getStatus() == AsyncTask.Status.RUNNING){ getImgToSaveCacheTask.cancel(true); } mCache.clearCache(); System.gc(); } private void initViews() { btn_save = (Button) findViewById(R.id.btn_save); btn_show = (Button) findViewById(R.id.btn_show); btn_getsize = (Button) findViewById(R.id.btn_getsize); btn_remove = (Button) findViewById(R.id.btn_remove); tv_size = (TextView) findViewById(R.id.tv_size); img_show = (ImageView) findViewById(R.id.img_show); } private void initEvents() { btn_save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { saveToCache(imgUrl); } }); btn_show.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showImg(imgUrl); } }); btn_getsize.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String cacheSize = mCache.getSize(); tv_size.setText(tv_size.getText() + cacheSize); } }); btn_remove.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mCache.removeFromCache(mCache.hashKeyForDisk(imgUrl)); } }); } /**顯示圖片*/
    private void showImg(String imgUrl) { String cacheKey = mCache.hashKeyForDisk(imgUrl); Bitmap bitmap = mCache.getBitmapFromCache(cacheKey);//從緩存中獲取圖片bitmap if(bitmap != null){ BitmapDrawable drawable = null; Resources resources = getResources(); drawable = new BitmapDrawable(resources, bitmap); //設置背景圖片 if(Build.VERSION.SDK_INT >= 16) { img_show.setBackground(drawable); }else{ img_show.setBackgroundDrawable(drawable); } } } /**保存圖標到緩存中*/
    private void saveToCache(String imgUrl){ //若是已經下載過來,那麼不須要從新下載
        String cacheKey = mCache.hashKeyForDisk(imgUrl); Bitmap bitmap = mCache.getBitmapFromCache(cacheKey);//從緩存中獲取圖片bitmap
        if(bitmap == null){ //判斷是否有網絡,此處註釋掉 //if (HttpUtil.isNetworkAvailable(MainActivity.this)) { //執行異步任務
                GetImgToSaveCacheTask getImgTask = new GetImgToSaveCacheTask(); getImgTask.execute(imgUrl); /*} else { this.showShortToast(getResources().getString(R.string.httpError)); }*/ } } /** * 保存圖標異步請求類 */
    public class GetImgToSaveCacheTask extends AsyncTask<String, Void, String> { @Override protected void onPreExecute() { //showProgressDialog("");//顯示加載對話框
 } @Override protected String doInBackground(String... params) { String data = ""; if(! isCancelled()){ try { if(params[0].equals("")){ data = ""; }else{ //下載圖片並緩存 BitmapFactory.Options opts = new BitmapFactory.Options(); String cacheKey = mCache.hashKeyForDisk(params[0]); Bitmap bitmap = null; synchronized(mCache.mDiskCacheLock){ if(mCache.getBitmapFromCache(cacheKey) == null) { //若是緩存中無圖片,則添加到磁盤緩存和內存緩存中 bitmap = BitmapFactory.decodeStream(new URL(params[0]).openConnection().getInputStream(), null, opts); mCache.addBitmapToMemoryCache(cacheKey, bitmap); mCache.addBitmapToDiskCache(cacheKey, bitmap); } else if(mCache.mMemoryCache.get(cacheKey) == null) { //若是內存緩存中無圖片,則磁盤緩存中添加到內存緩存中 bitmap = mCache.getBitmapFromDiskCache(cacheKey); mCache.addBitmapToMemoryCache(cacheKey, bitmap); } else if(mCache.getBitmapFromDiskCache(cacheKey) == null) { //若是磁盤緩存中無圖片,則從內存緩存中添加到磁盤緩存中 bitmap = mCache.getBitmapFromMemCache(cacheKey); mCache.addBitmapToDiskCache(cacheKey, bitmap); } } data = "success"; } } catch (Exception e) { e.printStackTrace(); } } return data; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); if(isCancelled()){ return; } try { if (result != null && !"".equals(result)){ //緩存成功,此處能夠進行其餘處理,好比顯示圖片
 } } catch (Exception e) { e.printStackTrace(); } finally { if(! isCancelled()){ //dismissProgressDialog();//隱藏加載對話框
 } } } } }

注意:網絡

緩存目錄示意圖:app

混淆配置

異步

參考資料

 Android DiskLruCache徹底解析,硬盤緩存的最佳方案ide

項目demo下載地址

 https://github.com/haiyuKing/CacheDemo

相關文章
相關標籤/搜索