• 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

  • 相关阅读:
    HDU 2895 编辑距离
    AC自动机
    HDU 1707 简单模拟 Spring-outing Decision
    HDU 1710 二叉树的遍历 Binary Tree Traversals
    Codeforces Round #521 (Div. 3) E. Thematic Contests
    Codeforces Round #521 (Div. 3) D. Cutting Out
    Codeforces Round #515 (Div. 3) E. Binary Numbers AND Sum
    Codeforces Round #510 (Div. 2) B. Vitamins
    Codeforces Round #510 (Div. 2) D. Petya and Array(树状数组)
    Codeforces Round #506 (Div. 3) 题解
  • 原文地址:https://www.cnblogs.com/whycxb/p/7245425.html
Copyright © 2020-2023  润新知