Android基于DiskLruCache做一个数据对象的缓存工具

Android面试题(22)-lruCache与DiskLruCache缓存详解 关于lruCache(最近最少使用)的算法,这是一个比较重要的算法,它的应用非常广泛,不仅仅在Android中使用,Linux系统等其他地方中也有使用;今天就来看一看这其中的奥秘;讲到LruCache,就不得不讲一讲LinkedHashMap,而对于LinkedHashMap,它继承的是HashMap,那么我们就先从HashMap开始看起吧;注:此篇博客所讲的所有知识都是在jdk1.8环境下的,j... 阅读详情

面试的时候被问过一次,如何对数据进行缓存,我答的数据库存储json字符串。被问到可不可以不用数据库,直接文件缓存对象。当然也是行的。之前看过郭神的博客:用lrucache与disklrucache缓存图片的。去年也仿着敲一个图片缓存工具类点击打开链接,今年来到新公司正好也遇到要离线加载数据的功能,换汤不换药的做了一个对象缓存到本地的工具类。

思路


方案

数据库我用的greendao,我发现greendao都有3.0的版本了,比2.0有较大的变化但更加方便了。

存对象(对象要序列化)

 public void putObject(String httpurl,Object ob){
        //将对象存入磁盘中
        //将url转md5key
        String key = hashKeyForDisk(httpurl);
        try {
            DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
            if (snapShot!=null){
                //说明磁盘里有数据了,就删掉
                mDiskLruCache.remove(key);
            }
            putObjectToMemoryCache(key,ob);
            //开始往磁盘放数据
            DiskLruCache.Editor editor = mDiskLruCache.edit(key);
            new Thread(new Put_Object_Runnable(editor,cacheDbBeanDao,ob,httpurl,key)).start();
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG,"向磁盘中存入"+httpurl+"的对象是异常");
        }
    }
 private class Put_Object_Runnable implements Runnable {
        private  DiskLruCache.Editor editor;
        private  CacheDbBeanDao cacheDbBeanDao;
        private Object ob;
        private String httpurl;
        private String key;

        public Put_Object_Runnable(DiskLruCache.Editor editor, CacheDbBeanDao cacheDbBeanDao, Object ob, String httpurl, String key) {
            this.editor = editor;
            this.cacheDbBeanDao = cacheDbBeanDao;
            this.ob = ob;
            this.httpurl = httpurl;
            this.key = key;
        }

        @Override
        public void run() {

            if (editor != null) {
                ObjectOutputStream  oos =null;
                try {
                    OutputStream outputStream = editor.newOutputStream(0);
                    oos= new ObjectOutputStream(outputStream);
                    oos.writeObject(ob);
                    oos.flush();
                    editor.commit();
                    //将记录存数据库
                    CacheDbBean cacheDbBean = cacheDbBeanDao.queryBuilder().where(CacheDbBeanDao.Properties.Key.eq(key)).unique();
                    if (cacheDbBean==null){
                        //第一次插入数据库
                        Log.i(TAG,"此数据第一次插入数据库"+httpurl);
                        cacheDbBeanDao.insert(new CacheDbBean(key,System.currentTimeMillis()));
                    }else{
                        Log.i(TAG,"此数据跟新数据库的时间"+httpurl);
                        cacheDbBean.setTime(System.currentTimeMillis());
                        cacheDbBeanDao.update(cacheDbBean);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    try {
                        editor.abort();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }finally {
                    if (oos!=null){
                        try {
                            oos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            flushCache();
        }
    }

从磁盘读取缓存数据

 /**
     * 根据http获取对象
     * @param httpurl
     * @return
     */

    public Object  getObjects(String httpurl){
        //将url转md5key
        String key = hashKeyForDisk(httpurl);
        //先从内存中查找
        Object objectFromMemoryCache = getObjectFromMemoryCache(key);
        if (objectFromMemoryCache==null){
            //内存中没有
            Log.i(TAG,"内存中没有此"+httpurl+"的对象");
            try {
                //查找key 对应的硬盘缓存
                DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
                if (snapShot != null) {
                    InputStream is = snapShot.getInputStream(0);
                    ObjectInputStream ois = new ObjectInputStream(is);
                    Log.i(TAG,"硬盘缓存中有此"+httpurl+"的对象");
                    return  ois.readObject();
                }else{
                    Log.i(TAG,"硬盘缓存中没有此"+httpurl+"的对象");
                    return null;
                }
            } catch (IOException e) {
                e.printStackTrace();
                Log.i(TAG,"读取硬盘缓存异常");
                return null;
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                Log.i(TAG,"读取硬盘缓存异常");
                return null;
            }
        }else{
            Log.i(TAG,"内存中有此"+httpurl+"的对象");
            return objectFromMemoryCache;
        }
    }

rxjava版

  public Flowable<Object> getObjectHH(String httpurl){

      return   Flowable.just(httpurl).map(new Function<String, String>() {
            @Override
            public String apply(String url) throws Exception {
                return  hashKeyForDisk(url);
            }
        }).subscribeOn(Schedulers.io()).flatMap(new Function<String, Publisher<?>>() {
            @Override
            public Publisher<?> apply(String key) throws Exception {
                Object objectFromMemoryCache = getObjectFromMemoryCache(key);
                //先从内存中查找
                if (objectFromMemoryCache==null){
                    //内存中没有
                    Log.i(TAG,"内存中没有此"+httpurl+"的对象");
                    //查找key 对应的硬盘缓存
                    try {
                        DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
                        if (snapShot != null) {
                            InputStream is = snapShot.getInputStream(0);
                            ObjectInputStream ois = new ObjectInputStream(is);
                            Log.i(TAG,"硬盘缓存中有此"+httpurl+"的对象");
                            objectFromMemoryCache= ois.readObject();
                            return Flowable.just(objectFromMemoryCache);
                        }else{
                            Log.i(TAG,"硬盘缓存中没有此"+httpurl+"的对象");
                            return Flowable.just(objectFromMemoryCache);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        Log.i(TAG,"读取硬盘缓存异常");
                        return  Flowable.just(objectFromMemoryCache);
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                        Log.i(TAG,"读取硬盘缓存异常");
                        return  Flowable.just(objectFromMemoryCache);
                    }

                }else{
                    Log.i(TAG,"内存中有此"+httpurl+"的对象");
                    return Flowable.just(objectFromMemoryCache);
                }
            }
        });

判断缓存是否存在或者或者缓存是否有效

 //判断一个接口是否有缓存以及缓存是否过期
    protected  boolean isHaveCacheOrCacheUseable(String httpurl){
        //是否有缓存
        String key=hashKeyForDisk(httpurl);
        DiskLruCache.Snapshot snapShot = null;
        try {
            snapShot = mDiskLruCache.get(key);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (snapShot==null){
            //说明磁盘没缓存
            return false;
        }else{
            //有磁盘缓存就判断缓存是否有效
            long currentTime = System.currentTimeMillis();//获取当前的系统时间
            CacheDbBean cacheDbBean = cacheDbBeanDao.queryBuilder().where(CacheDbBeanDao.Properties.Key.eq(key)).unique();
            if (cacheDbBean!=null){
                if ((currentTime-cacheDbBean.getTime())>5*1000){
                    //超过5秒过期
                    return false;
                }else{
                    return true;
                }
            }else{
                return false;
            }
        }
    }

效果:


副本:

package com.shan.library.utils;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
import android.util.Log;
import android.util.LruCache;

import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import io.reactivex.Flowable;

import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;


/**
 * Created by hcy on 2018/4/17.
 * func数据的三级缓存
 */
public class SELrucacheUtils {

    private static final String TAG = "SELrucacheUtils";

    private DiskLruCache mDiskLruCache;//硬盘缓存

    private LruCache<String, Object> mMemoryCache;//内存缓存

    private Context context;

    private int maxMemory;//程序最大的可用内存

    private DaoSession mDaoSession;


    private static volatile SELrucacheUtils instance = null;

    public static SELrucacheUtils getInstance(Context context, String cacheDirName){
        if (instance == null) {
            synchronized (SELrucacheUtils.class) {
                if (instance == null) {
                    instance = new SELrucacheUtils(context,cacheDirName);
                }
            }
        }

        return instance;
    }

    //判断一个接口是否有缓存以及缓存是否过期
    protected  boolean isHaveCacheOrCacheUseable(String httpurl){
        //是否有缓存
        String key=hashKeyForDisk(httpurl);
        DiskLruCache.Snapshot snapShot = null;
        try {
            snapShot = mDiskLruCache.get(key);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (snapShot==null){
            //说明磁盘没缓存
            return false;
        }else{
            //有磁盘缓存就判断缓存是否有效
            long currentTime = System.currentTimeMillis();//获取当前的系统时间
            CacheDbBean cacheDbBean = cacheDbBeanDao.queryBuilder().where(CacheDbBeanDao.Properties.Key.eq(key)).unique();
            if (cacheDbBean!=null){
                if ((currentTime-cacheDbBean.getTime())>5*1000){
                    //超过5秒过期
                    return false;
                }else{
                    return true;
                }
            }else{
                return false;
            }
        }
    }


















    private DaoSession daoSession;
    private CacheDbBeanDao cacheDbBeanDao;

    public SELrucacheUtils(Context context, String cacheDirName) {
        this.context = context;
        //初始化数据库
        //创建数据库shop.db"
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, "shop.db", null);
        //获取可写数据库
        SQLiteDatabase db = helper.getWritableDatabase();
        //获取数据库对象
        DaoMaster daoMaster = new DaoMaster(db);
        //获取Dao对象管理者
        daoSession = daoMaster.newSession();
        cacheDbBeanDao=daoSession.getCacheDbBeanDao();


        try {
            File cacheDir = getDiskCacheDir(context, cacheDirName);//获取缓存路径

            if (!cacheDir.exists()) {
                cacheDir.mkdirs();
            }
            /**
             * 缓存地址,应用版本,一个key对应几个文件,最大缓存值
             */
            mDiskLruCache = DiskLruCache.open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024);

            maxMemory = (int) Runtime.getRuntime().maxMemory();

            int cacheSize = maxMemory / 8;
            mMemoryCache = new LruCache<String, Object>(cacheSize) {
                @Override
                protected int sizeOf(String key, Object value) {
                    return super.sizeOf(key, value);
                }
            };

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭硬盘缓存
     */
    public void closeDiskLruCache() {
        try {
            if (mDiskLruCache != null) {
                mDiskLruCache.close();//关闭缓存
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 计算所有图片的缓存大小
     */
    public long countCache() {
        if (mDiskLruCache != null) {
            long size = mDiskLruCache.size();
            return size;
        } else {
            return 0;
        }
    }


    /**
     * 删除缓存
     */

    protected void deleteCache() throws IllegalStateException {
        if (mDiskLruCache != null) {
            try {
                mDiskLruCache.delete();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                throw new IllegalStateException("cache is closed");
            }
        }
    }


    /**
     * 将对象保存到内存中
     *
     * @param key
     * @param ob
     */

    public void putObjectToMemoryCache(String key, Object ob) {
           mMemoryCache.put(key, ob);
    }




    //同步缓存记录
    private  void flushCache() {
        if (mDiskLruCache != null) {
            try {
                mDiskLruCache.flush();
            } catch (IOException e) {
                Log.i(TAG, "mDiskLruCache.flush() Error");
            } catch (IllegalStateException e) {
                Log.i(TAG, "mDiskLruCache.flush() ErrorE");
            }
        }
    }


    /**
     * 将对象放入
     * @param httpurl
     * @param ob
     */

    public void putObject(String httpurl,Object ob){
        //将对象存入磁盘中
        //将url转md5key
        String key = hashKeyForDisk(httpurl);
        try {
            DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
            if (snapShot!=null){
                //说明磁盘里有数据了,就删掉
                mDiskLruCache.remove(key);
            }
            putObjectToMemoryCache(key,ob);
            //开始往磁盘放数据
            DiskLruCache.Editor editor = mDiskLruCache.edit(key);
            new Thread(new Put_Object_Runnable(editor,cacheDbBeanDao,ob,httpurl,key)).start();
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG,"向磁盘中存入"+httpurl+"的对象是异常");
        }
    }


    private class Put_Object_Runnable implements Runnable {
        private  DiskLruCache.Editor editor;
        private  CacheDbBeanDao cacheDbBeanDao;
        private Object ob;
        private String httpurl;
        private String key;

        public Put_Object_Runnable(DiskLruCache.Editor editor, CacheDbBeanDao cacheDbBeanDao, Object ob, String httpurl, String key) {
            this.editor = editor;
            this.cacheDbBeanDao = cacheDbBeanDao;
            this.ob = ob;
            this.httpurl = httpurl;
            this.key = key;
        }

        @Override
        public void run() {

            if (editor != null) {
                ObjectOutputStream  oos =null;
                try {
                    OutputStream outputStream = editor.newOutputStream(0);
                    oos= new ObjectOutputStream(outputStream);
                    oos.writeObject(ob);
                    oos.flush();
                    editor.commit();
                    //将记录存数据库
                    CacheDbBean cacheDbBean = cacheDbBeanDao.queryBuilder().where(CacheDbBeanDao.Properties.Key.eq(key)).unique();
                    if (cacheDbBean==null){
                        //第一次插入数据库
                        Log.i(TAG,"此数据第一次插入数据库"+httpurl);
                        cacheDbBeanDao.insert(new CacheDbBean(key,System.currentTimeMillis()));
                    }else{
                        Log.i(TAG,"此数据跟新数据库的时间"+httpurl);
                        cacheDbBean.setTime(System.currentTimeMillis());
                        cacheDbBeanDao.update(cacheDbBean);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    try {
                        editor.abort();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }finally {
                    if (oos!=null){
                        try {
                            oos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            flushCache();
        }
    }


 /*   *
     * 存入对象
     *//*

     public void  putObject(String httpurl,Object ob){
         //将url转md5key
         String key = hashKeyForDisk(httpurl);
         Object objectFromMemoryCache = getObjectFromMemoryCache(key);
         if (objectFromMemoryCache==null){
             Log.i(TAG,"向内存中存入"+httpurl+"的对象");
             putObjectToMemoryCache(key,ob);
         }
         //查找key 对应的硬盘缓存
         try {
             DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
             if (snapShot==null){
                 Log.i(TAG,"向磁盘中存入"+httpurl+"的对象");
                 DiskLruCache.Editor editor = mDiskLruCache.edit(key);

             }else{
                 Log.i(TAG,"向磁盘中已经存在"+httpurl+"的对象");
             }
         } catch (IOException e) {
             Log.e(TAG,"向磁盘中存入"+httpurl+"的对象是异常");
             e.printStackTrace();
         }

     }*/

    /**
     * 根据http获取对象
     * @param httpurl
     * @return
     */

    public Object  getObjects(String httpurl){
        //将url转md5key
        String key = hashKeyForDisk(httpurl);
        //先从内存中查找
        Object objectFromMemoryCache = getObjectFromMemoryCache(key);
        if (objectFromMemoryCache==null){
            //内存中没有
            Log.i(TAG,"内存中没有此"+httpurl+"的对象");
            try {
                //查找key 对应的硬盘缓存
                DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
                if (snapShot != null) {
                    InputStream is = snapShot.getInputStream(0);
                    ObjectInputStream ois = new ObjectInputStream(is);
                    Log.i(TAG,"硬盘缓存中有此"+httpurl+"的对象");
                    return  ois.readObject();
                }else{
                    Log.i(TAG,"硬盘缓存中没有此"+httpurl+"的对象");
                    return null;
                }
            } catch (IOException e) {
                e.printStackTrace();
                Log.i(TAG,"读取硬盘缓存异常");
                return null;
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                Log.i(TAG,"读取硬盘缓存异常");
                return null;
            }
        }else{
            Log.i(TAG,"内存中有此"+httpurl+"的对象");
            return objectFromMemoryCache;
        }
    }



    public Flowable<Object> getObjectHH(String httpurl){

      return   Flowable.just(httpurl).map(new Function<String, String>() {
            @Override
            public String apply(String url) throws Exception {
                return  hashKeyForDisk(url);
            }
        }).subscribeOn(Schedulers.io()).flatMap(new Function<String, Publisher<?>>() {
            @Override
            public Publisher<?> apply(String key) throws Exception {
                Object objectFromMemoryCache = getObjectFromMemoryCache(key);
                //先从内存中查找
                if (objectFromMemoryCache==null){
                    //内存中没有
                    Log.i(TAG,"内存中没有此"+httpurl+"的对象");
                    //查找key 对应的硬盘缓存
                    try {
                        DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
                        if (snapShot != null) {
                            InputStream is = snapShot.getInputStream(0);
                            ObjectInputStream ois = new ObjectInputStream(is);
                            Log.i(TAG,"硬盘缓存中有此"+httpurl+"的对象");
                            objectFromMemoryCache= ois.readObject();
                            return Flowable.just(objectFromMemoryCache);
                        }else{
                            Log.i(TAG,"硬盘缓存中没有此"+httpurl+"的对象");
                            return Flowable.just(objectFromMemoryCache);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        Log.i(TAG,"读取硬盘缓存异常");
                        return  Flowable.just(objectFromMemoryCache);
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                        Log.i(TAG,"读取硬盘缓存异常");
                        return  Flowable.just(objectFromMemoryCache);
                    }

                }else{
                    Log.i(TAG,"内存中有此"+httpurl+"的对象");
                    return Flowable.just(objectFromMemoryCache);
                }
            }
        });




     /*  return  Flowable.just(httpurl).map((url)->{
            return  hashKeyForDisk(url);
        }).flatMap((key)->{
            Object objectFromMemoryCache = getObjectFromMemoryCache(key);
            //先从内存中查找
            if (objectFromMemoryCache==null){
                //内存中没有
                Log.i(TAG,"内存中没有此"+httpurl+"的对象");
                //查找key 对应的硬盘缓存
                try {
                    DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
                    if (snapShot != null) {
                        InputStream is = snapShot.getInputStream(0);
                        ObjectInputStream ois = new ObjectInputStream(is);
                        Log.i(TAG,"硬盘缓存中有此"+httpurl+"的对象");
                        objectFromMemoryCache= ois.readObject();
                        return Flowable.just(objectFromMemoryCache);
                    }else{
                        Log.i(TAG,"硬盘缓存中没有此"+httpurl+"的对象");
                        return Flowable.just(objectFromMemoryCache);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.i(TAG,"读取硬盘缓存异常");
                    return  Flowable.just(objectFromMemoryCache);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                    Log.i(TAG,"读取硬盘缓存异常");
                    return  Flowable.just(objectFromMemoryCache);
                }

            }else{
                Log.i(TAG,"内存中有此"+httpurl+"的对象");
                return Flowable.just(objectFromMemoryCache);
            }
        }).subscribeOn(Schedulers.io());*/

    }


    /**
     * 从内存中获取对象
     * @param key
     * @return
     */
    public Object getObjectFromMemoryCache(String key) {
        return mMemoryCache.get(key);
    }

    /**
     * 使用MD5算法对传入的key进行加密并返回。
     */
    private String hashKeyForDisk(String key) {
        String cacheKey;
        try {
            final MessageDigest mDigest = MessageDigest.getInstance("MD5");
            mDigest.update(key.getBytes());
            cacheKey = bytesToHexString(mDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            cacheKey = String.valueOf(key.hashCode());
        }
        return cacheKey;
    }


    private String bytesToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(0xFF & bytes[i]);
            if (hex.length() == 1) {
                sb.append('0');
            }
            sb.append(hex);
        }
        return sb.toString();
    }










    /**
     * 获取缓存路径
     *
     * @param context
     * @param cacheFileName
     * @return
     */

    private File getDiskCacheDir(Context context, String cacheFileName) {

        String cachePath;
        if (context != null) {
            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                    || !Environment.isExternalStorageRemovable()) {
                if (context.getExternalCacheDir() != null) {
                    if (context.getExternalCacheDir().getPath() != null) {
                        cachePath = context.getExternalCacheDir().getPath();
                    } else {
                        cachePath = context.getCacheDir().getPath();
                    }
                } else {
                    cachePath = "/data/data/com.wyt.hcy.learningenglishapp/cache";
                }


            } else {
                cachePath = context.getCacheDir().getPath();
            }
        } else {
            cachePath = "/data/data/com.wyt.hcy.learningenglishapp/cache";
        }

        return new File(cachePath + File.separator + cacheFileName);

    }


    /**
     * 获取当前应用程序的版本号。
     */
    private int getAppVersion(Context context) {
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(),
                    0);
            return info.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return 1;
    }

}










DiskLruCacheDemo:Android磁盘缓存实用教程 DiskLruCache是Android开发中用于管理应用内部磁盘缓存的一个工具类。它基于最近最少使用(LRU)算法,维护一个固定大小的缓存池,使得应用可以有效地利用存储空间来缓存数据,如图片、文件等。这个缓存池对开发者来说是透明的,用户无需关心具体的存储细节。LRU(Least Recently Used,最近最少使用)算法最早由C.J. Date在其著作《An Introduction to Database Systems》中提出。它是一种广泛使用的缓存淘汰算法,用于管理有限的缓存资源。 阅读详情

相关推荐

Android高效图片加载与缓存实践:LruCache与DiskLruCache组合使用

本文还有配套的精品资源,点击获取 简介:本项目演示了如何在Android中利用LruCache和DiskLruCache来优化图片加载过程。LruCache用于内存缓存,而DiskLruCache则用于持久化存储。通过这种双重缓存策略,可显著提升应用性能,减少等待时间,降低系统资源消耗。通过下载并分析 PhotosWallDemo 项目源码,开发者将学习到如何...

weixin_42593549的博客 1026

Android Download机制详解(一)DocumentUI部分

在Android中Google为我们集成了一套十分便利的Download机制,用来下载网络上的资源文件。以此省去了我们编写和维护大量与Download相关的代码。 组成 Android中Download由三个部分组成: 1.DocumentsUI ----->/frameworks/base/packages/DocumentsUI/ 2.DownloadManager --...

weixin_30776863的博客 892

android中DiskLruCache缓存类

android三级缓存的DiskLruCache类的代码以及其他使用到的工具类

Android Uri 转 Path

文件管理器的组成 调用系统自带的文件管理器有如下几个选项,分为两类 系统自带的文件管理器 第三方集成到系统管理器中 下面是调用选择文件方法后,调用系统文件管理器出来的界面 网上可以搜到很多 Uri 转路径的方法,但都是互相抄袭根本没经过验证的。现在最新是 Android 10,而网上那些方法,大多连 Android 7 引入文件权限(fileProvider)都不支持。本着认真仔细的研究,我安...

司马懿的西山居 2万+

Android缓存之DiskLruCache磁盘缓存的使用

DiskLruCache和LruCache不同的是,LruCache是内存缓存,而DiskLruCache是指磁盘缓存,顾名思义就是把文件缓存到磁盘,也也就是手机的内存卡中。接下来先简单介绍DiskLruCache的使用方法。 下载源码 DiskLruCache并没有在 SDK中存在,但又是谷歌提倡的。所以我们要先把DiskLruCache的源码下载下来。 我们可以通过下面这个地址下载源码:https://github.com/JakeWharton/DiskLruCache/tree/master/src/main/java/com/jakewharton/disklrucache 然后

华为HCIA-Datacom实战:200人企业园区网从规划到部署全流程解析

本文详细解析了华为HCIA-Datacom认证实战中200人企业园区网的规划与部署全流程。从需求分析、组网架构设计到设备选型、VLAN划分及安全策略实施,全面覆盖园区网建设的关键环节,特别针对部门隔离、无线覆盖和基础安全防护等典型场景提供可落地的解决方案。

f0g1h2的博客 710

Android DiskLruCache完全解析,硬盘缓存的最佳方案

Android DiskLruCache完全解析,硬盘缓存的最佳方案

QG 1868

osgEarth shapefile矢量生成三维模型案例 2.boston.earth

osgEarth shapefile矢量生成三维模型案例 2.boston.earth 波士顿城市建筑、路灯、公园、道路shp矢量生成三维模型案例。

qq_24934183的博客 3542

深入理解Linux文件系统及日志分析 超简单易懂

深入理解Linux文件系统及日志分析一、INODE与BLOCK1.1、inode与block概述1.2、inode的内容二、软连接与硬链接2.1、连接文件三、恢复误删除的文件3.1、EXT类型文件恢复1、下面将介绍使用extundelete工具如何恢复误删除的文件。 一、INODE与BLOCK 1.1、inode与block概述 文件是存储在硬盘上的,硬盘最小存储叫做扇区,每个扇区512字节 操作系统读取硬盘信息,不会一个一个扇区读取。实际情况一下连续读取 多个扇区,一次性读取多个扇区,叫做块(Block)

CNFANG的博客 599

python 携程登陆_Python 学习练习之用户登录接口

目的:用python实现简单用户注册,登陆,加黑功能,放个流程图吧。以下内容仅为练习 执行流程:[root@zabbix login]# python user_login.pyusername:tompassword:123456Are you want to register ? [y/n]yRegister successful,Please relogin ![root@zabbix lo...

weixin_28679635的博客 516

GlobalPlatform Technology Secure Channel Protocol ‘03‘ 标准 - 安全通道协议简介

按照GlobalPlatform Technology Secure Channel Protocol '03' (SCP03)标准,描述了如何利用S-MAC,S-RMAC,S-ENC进行安全通信的过程。

mmmx777的专栏 6091

Android三级缓存原理及用LruCache、DiskLruCache实现一个三级缓存的ImageLoader

Android图片三级缓存原理及用LruCache、DiskLruCache动手打造一个三级缓存的ImageLoader三级缓存概述三级缓存的流程强引用 、弱引用 、软引用、虚引用的区别:内存缓存LruCacheDiskLruCache: 三级缓存概述 缓存是一种通用的思想可以用在很多场景中,但在实际的开发中经常用于Bitmap的缓存,用于提高图片的加载效率、提升产品的用户体验和节省用户流量。目...

马彦虎的博客 5007

ABAP Cloud 开发教程的文章目录

本教程涵盖 ABAP 云端 Client 处理、多租户架构、ABAP Cloud开发、动态编程优化、SQL语法改进等技术主题。最新版本1.0.0(更新至2025-12-12),包含197篇文章,重点文章包括《ABAP Client Handling与隔离机制》《ABAP Platform 2021泛型编程》《SAP BTP ABAP多租户应用开发》等,为开发者提供从基础到进阶的实战指南。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1795

【安卓中的缓存策略系列】安卓缓存策略之磁盘缓存DiskLruCache

安卓中的缓存包括两种情况即内存缓存与磁盘缓存,其中内存缓存主要是使用LruCache这个类,其中内存缓存我在【安卓中的缓存策略系列】安卓缓存策略之内存缓存LruCache中已经进行过详细讲解,如看官还没看过此博客,建议看官先去看一下。 我们知道LruCache可以让我们快速的从内存中获取用户最近使用过的Bitmap,但是我们无法保证最近访问过的Bitmap都能够保存在缓存中,像类似GridVie

(* ̄︶ ̄) 6万+

09 SAP CPI 访问公共API接口

我在网上找了一个公共API,入参输入汉字返回拼音。至此,一个真正的访问API的接口就做好了。点击保存时可看到红叉报错。

SAP CPI 477

AFSim2.9.0学习笔记 —— 2、AFSim的Wizard软件概述(ArkSIM集成开发环境 (IDE))

AFSim2.9.0学习笔记 —— 2、AFSim的Wizard软件详述(ArkSIM集成开发环境 (IDE))

916

【Android】Android内存缓存LruCache与DiskLruCache的使用及实现原理

在Android中,通常会通过缓存策略来优化性能,同时也会减少不必要的流量消耗。比如,用户第一次使用网络加载一张图片后,下次加载这张图片的时候,并不会从网络加载,而是会从内存或者磁盘加载这张图片。

2302_79323248的博客 866

2026华为OD面试题029:勇攀数字高峰

在给定的数字地形图里寻找登山路径,数字代表当前位置的海拔高度。要求从最低海拔出发,不断攀登,最终到达最高山峰。地图保证最低海拔和最高山峰都只有一个。 登山规则: - 路径上的海拔必须严格递增 - 只能向上下左右 4 个方向移动 - 路径必须从最低海拔开始,到最高海拔结束 - 每个地点只能走一次 - 每一步的攀登高度差必须大于 0,且不超过指定值 `K` 输出满足条件的登山路径的数量。

琅嬛福地 114

Android DiskLruCache 源码解析 硬盘缓存的绝佳方案

= null) {还是那句,因为每个实体都是文件,所以你返回的is是个FileInputStream,你可以利用is读取出里面的内容,然后do what you want .好了,关于Cache最主要就是存取了,了解这几点,就可以往下去看源码分析了。还记得第一点说的journal文件么,首先就是它了。

2501_90366122的博客 957

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

缓存工具DiskLruCache

DiskLruCache是一个十分好用的android缓存工具,我们可以从GitHub上 下载其源码:https://github.com/JakeWharton/DiskLruCache DiskLruCache所有的数据都存储在 /storage/emulated/0/Android/data/应用包名/cache/XXX 文件夹中(你也可以修改,但不建议这样做,原因请继续往下看),这个

JOE 759

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Android缓存机制详解之硬盘缓存DiskLruCache

android 大图片OOM处理,DiskLruCache高效加载图片最佳方案

wuchuang 1277

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Android使用磁盘缓存DiskLruCache

DiskLruCache 不同于LruCache,LruCache是将数据缓存到内存中去,而DiskLruCache是外部缓存,例如可以将网络下载的图片永久的缓存到手机外部存储中去,并可以将缓存数据取出来使用,DiskLruCache不是google官方所写,但是得到了官方推荐,DiskLruCache没有编写到SDK中去,如需使用可直接copy这个类到项目中去。DiskLruCache地址: h

小马快跑的博客 1325
上一篇: 积累一些关于ANDROID TV开发的经验
下一篇: Android 对Tv开发的总结
泡温泉的咸鱼
博客等级 码龄11年 39粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值