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


版權聲明:本文為HaiyuKing原創文章,轉載請注明出處!

前言

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

效果圖

代碼分析

內存緩存LruCache和磁盤緩存DiskLruCache根據實際情況進行緩存,有時候需要兩者都用到,有時候只用磁盤緩存即可。

使用步驟

一、項目組織結構圖

注意事項:

1、  導入類文件后需要change包名以及重新import R文件路徑

2、  Values目錄下的文件(strings.xml、dimens.xml、colors.xml等),如果項目中存在,則復制里面的內容,不要整個覆蓋

二、導入步驟

將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)

三、使用方法

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();//隱藏加載對話框
                }
            }
        }
    }
}

注意:

緩存目錄示意圖:

混淆配置

參考資料

 Android DiskLruCache完全解析,硬盤緩存的最佳方案

項目demo下載地址

 https://github.com/haiyuKing/CacheDemo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM