安卓本地缓存数据管理工具类

安卓开发有时候需要保存数据到手机本地,这样就可以减少重复请求后台获取数据的麻烦。
安卓缓存方式有5种,远端缓存数据就是后台服务器帮我们保存数据;近端的客户端缓存有三种。
第一种就是SharePreference缓存,这也是我们安卓开发用的最多的客户端缓存方式,特别就是比较简单:

               val sharedPreferences = getSharedPreferences("fenji", Context.MODE_PRIVATE)
                val edit = sharedPreferences.edit()
                edit.putString("save_string","保存本地数据")
                edit.commit() //必须提交才能生效
                val cacheString = sharedPreferences.getString("save_string", "")
                LogUtils.e(">>>>>>>>>>>>>>>>", "保存的SharePreferences数据:$cacheString")

这里我们发现ContextWrapper是我们Application的直接父类,而且Application的生命周期是跟随我们的App从打开创建到App被退出到后台被杀死一直存在的。然后ContextWrapper的直接父类是Context,这里我们就可以知道只要我们获取到Context对象就可以获取到SharedPreferences对象进行本地缓存,缓存方式类似与Java的Map集合,一个Key对应一个Value进行保存。

优点:简单、方便。

第二种:数据库缓存。
因为安卓Framwork框架内置了SQlite轻量级数据库,虽然增删改查的操作都依赖与sdl语句的执行,但是随着安卓开源框架的增加,安卓也有很多解决写sql语句痛点的开源框架:Geendao.
这个数据库缓存集成简单,管理除了后期数据库升级会删除之前数据库的所有数据,需要自己手动的迁移之前数据库的表之外,其他的都是直接配置就好了。

/**
 * 创建一个GreenDao实体类,实现对数据的增删改查
 */
public class GreenDaoUtils {

    private final DaoSession mDaoSession;
    private static GreenDaoUtils daoInstance;
    private static KeyValueEntityDao mDaoGuideEntityDao;


    /**
     * 初始化GreenDao数据库
     * @param context
     */
    private GreenDaoUtils(Context context){
        MyDevOpenHelper devOpenHelper = new MyDevOpenHelper(context, "fj_reading_db", null);
        DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
        mDaoSession = daoMaster.newSession();
        mDaoGuideEntityDao = mDaoSession.getKeyValueEntityDao();
    }

    /**
     * 获取单例实例对象
     * @param context
     * @return
     */
    public static GreenDaoUtils getDaoInstance(Context context){
        if(daoInstance == null){
            synchronized (GreenDaoUtils.class){
                if(daoInstance == null){
                    daoInstance = new GreenDaoUtils(context);
                }
            }
        }
        return daoInstance;
    }
    /**
     * 查询引导实例对象
     */
    public String queryValueEntityByKey(String guideName){
        try {
            List<KeyValueEntity> entityList = mDaoGuideEntityDao.queryBuilder().list();// 获取表的所有数据列表
            for (KeyValueEntity guideEntity : entityList) {
                if (guideName.equals(guideEntity.getKey())) {
                    return guideEntity.getValue();
                }
            }
        }catch (Exception e){
            LogUtils.e(">>>>>>>>>>>",e.getMessage());
        }
        return "";
    }
    /**
     * 创建根据Key,保存Value的方法
     */
    public void setEntityDaoValueByKey(String key,String value){
        KeyValueEntity valueEntity = new KeyValueEntity(key, value);
        mDaoGuideEntityDao.insertOrReplace(valueEntity);
    }
}

其实GreenDao可以解决安卓客户端所有的数据缓存场景,而且也是非常方便的。只要把我们需要缓存的数据对象放入到你指定的生成greendao文件目录的entity文件夹下,然后缓存数据类加入注解:

@Entity
public class KeyValueEntity {

然后重新编译项目GreenDao就会自动给你的缓存数据对象生成一个Dao文件类,类名是你的缓存文件的类名+Dao。然后我们通过这个Dao对象进行数据的增删改查操作。
第三种:文件缓存。
如果说安卓数据库、SharePreference缓存的存放目录是存在手机内置内存的,那么文件缓存则是保存数据到手机外置内存卡的。把文件保存到外置内存的好处就是我们可以随时查看,手机内置内存除非是手机被root的情况下才能查看,要不然一般用户是无法查看的。
文件保存除了需要创建一个文件的保存目录以外,还需要让手机获取到读写内存卡的权限。

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

然后让你需要缓存的数据实体类继承Serializable接口表示这个数据实体类是可以序列化二进制流的,然后编写一个数据缓存工具类:

/**
 * 保存服务器的数据到本地,单例模式
 */
class CacheServerDataUtils private constructor() {

    /**
     * 缓存一个序列化对象到本地文件
     */
    fun saveServerDataObjectToLocal(context: Context?, `object`: Any?, fileName: String?) {
        try {
            val filePath = createFileToSaveServerData(context, fileName) //获取文件最后的修改时间为文件名
            val fs = FileOutputStream(filePath)
            val os = ObjectOutputStream(fs)
            os.writeObject(`object`)
            os.close()
            fs.close()
        } catch (ex: Exception) {
            LogUtils.e("缓存对象数据异常:" + ex.message)
        }

    }

    /**
     * 反序列化一个本地文件对象
     */
    fun getLocalFileToDataObject(context: Context?, fileName: String?): Any? {
        var newPerson: Any? = null
        try {
            val filePath = createFileToSaveServerData(context, fileName) //获取本地文件的文件绝对路径
            val file = File(filePath)
            if (file.exists()) {
                val fileInputStream = FileInputStream(file)
                val oin = ObjectInputStream(fileInputStream)
                newPerson = oin.readObject()
                oin.close()
                fileInputStream.close()
            }
        } catch (e: Exception) {
            LogUtils.e("反序列化对象数据异常:" + e.message)
        }

        return newPerson
    }

    /**
     * 提供一个方法,来判断文件的最后修改时间
     */
    private fun getFileLastModifiedTime(context: Context?, fileName: String?): Long {
        val filePath = createFileToSaveServerData(context, fileName)
        val cacheFile = File(filePath)
        if (cacheFile.exists()) {
            val cal = Calendar.getInstance()
            cal.timeInMillis = cacheFile.lastModified()
            val time = cal.time
            return time.time
        }
        return 0
    }

    /**
     * 提供一个方法,判断文件的修改时间是否大于刷新时间,来刷新界面
     */
    fun isNeedRefreshLocalCacheData(context: Context?, fileName: String?): Boolean {
        //获取一个当前的时间
        val currentTimeMillis = System.currentTimeMillis()
        //获取一个文件最后修改时间
        val lastModifiedTime = getFileLastModifiedTime(context, fileName)
        //判断文件的最后保存时间是否大于5分钟
        return currentTimeMillis - lastModifiedTime > 1000 * 60 * 5
    }
    /**
     * 创建一个文件夹保存到本地
     */
    private fun createFileToSaveServerData(context: Context?, fileName: String?): String {
        //获取sdk路径
        val phoneSDPath = SystemUtil.getPhoneCacheSDPath(context)
        var cacheFileName = ""
        if (ObjectUtils.isNotEmpty(phoneSDPath)) {
            //获取用户的唯一标识
            val userId = UserPreferences.keyUserId
            val filePath = (phoneSDPath + File.separator + AppUtils.getAppVersionName()
                    + File.separator + userId + File.separator)
            //创建一个文件
            val cacheFile = File(filePath)

            // 如果文件不存在,则创建一个新文件
            try {
                if (!cacheFile.exists()) {

                    cacheFile.mkdirs() // 可以创建文件多层目录
                }
            } catch (e: Exception) {
                LogUtils.e("创建一个文件夹异常:" + e.message)
            }

            cacheFileName = cacheFile.absolutePath + File.separator + "$fileName.txt"
        }
        return cacheFileName
    }

    /**
     * 根据文件名删除指定的缓存文件
     */
    fun deleteCacheFileByName(context: Context?, fileName: String?){
        val cacheFileName = createFileToSaveServerData(context, fileName)
        LogUtils.e("cacheFileName:$cacheFileName")
        try{
            val cacheFile = File(cacheFileName)
            if(cacheFile.exists()){
                cacheFile.delete()
            }
        }catch (e: Exception){
            LogUtils.e("删除缓存文件夹异常:" + e.message)
        }
    }
    companion object {

        private var cacheInstance: CacheServerDataUtils? = null


        fun getDataCacheInstance(): CacheServerDataUtils {
            if (cacheInstance == null) {
                synchronized(CacheServerDataUtils::class.java) {
                    if (cacheInstance == null) {
                        cacheInstance = CacheServerDataUtils()
                    }
                }
            }
            return cacheInstance as CacheServerDataUtils
        }
    }
}

到这里我们就可以实现文件缓存了,但是如果是外置内存卡缓存数据,这里就可以保存很多的数据,只要你不卸载App,缓存到外置内存的数据是不会被清理掉的。一般的App都会在设置界面,有一个显示手机内存的选项,用户可以点击按钮进行手机外置内存的清除操作。

/**
 * 缓存清理工具类,文件缓存分临时和文件缓存
 * 1)分享保存到手机的图片为临时缓存,getCacheDir()。
 * 2)文章内容的数据对象为文件缓存,用户退出登录的时候清除所有用户数据 context.getExternalCacheDir()。
 * 3)用户在App点击清理缓存是删除本地缓存的文件夹,就是getCacheDir()文件下的缓存文件。
 * 该工具类管理缓存文件的目录和删除本地缓存文件的方法
 */

public class AppCacheFileManager {

    /**
     * 获取App缓存目录下的所有文件的大小
     * @param context
     * @return
     */
    public static String getTotalCacheSize(Context context) {
        long cacheSize = 0;
        try {
            cacheSize += getFolderSize(context.getCacheDir());
            //当SD卡存在或者SD卡不可被移除的时候,就调用getExternalCacheDir()方法来获取缓存路径,
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                cacheSize += getFolderSize(context.getExternalCacheDir());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return getFormatSize(cacheSize);
    }

    /**
     * 清除app临时缓存数据(系统内部/data/data/.../cache/)目录下的数据
     */
    public static void cleanAppCacheDirFlies(Context context) {
        File cacheCacheDir = context.getCacheDir();
        deleteDirFiles(cacheCacheDir);
    }

    /**
     * 清除app所有缓存数据(SD上的/data/data/.../cache/及系统内部/data/data/.../cache/)
     * @param context
     */
    public static void clearAllCache(Context context) {
        cleanAppCacheDirFlies(context);
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            File externalCache = context.getExternalCacheDir();
            deleteDirFiles(externalCache);
        }
    }

    private static boolean deleteDirFiles(File dirFile) {
        if (ObjectUtils.isNotEmpty(dirFile) && dirFile.isDirectory()) {
            String[] children = dirFile.list();
            for (String str: children) {
                boolean success = deleteDirFiles(new File(dirFile, str));
                if (!success) {
                    return false;
                }
            }
        } else if (ObjectUtils.isNotEmpty(dirFile)) {
            return dirFile.delete();
        }
        return false;


    }

    // 获取文件
    // Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/
    // 目录,一般放一些长时间保存的数据
    // Context.getExternalCacheDir() -->SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据
    public static long getFolderSize(File file) {
        long size = 0;
        File[] fileList = file.listFiles();
        for (File localFile: fileList) {
            // 如果下面还有文件
            if (localFile.isDirectory()) {
                size = size + getFolderSize(localFile);
            } else {
                size = size + localFile.length();
            }
        }
        return size;
    }

    /**
     * 格式化单位
     * @param size
     */

    public static String getFormatSize(double size) {
        double kiloByte = size / 1024;
        if (kiloByte < 1) {
            return (String.valueOf(size)).concat("Byte");
        }
        double megaByte = kiloByte / 1024;
        if (megaByte < 1) {
            BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
            return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString().concat("KB");
        }
        double gigaByte = megaByte / 1024;
        if (gigaByte < 1) {
            BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
            return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString().concat("MB");
        }
        double teraBytes = gigaByte / 1024;
        if (teraBytes < 1) {
            BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString().concat("GB");
        }
        BigDecimal result4 = new BigDecimal(teraBytes);
        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString().concat("TB") ;
    }
}

这里有一个问题就是,我们保存的数据到底该放在手机内存卡的那个位置?
扩展资料:
1)Android 文件外/内部存储的获取各种存储目录路径
2)android路径获取
这里我们知道安卓手机App创建的时候会有一个内部存储空间,路径就是手机内部存储内存的data/data/应用程序包名。
开发人员可以借助android studio的Device File Explorer工具查看,打开这个工具的位置在As面板的最左下角。App内置内存路径是我们查看的时候是data/data,但是打印出来就可以是下面这个dada/user/0,都是指向的App的内置内存。

/data/user/0/

外置内存我们会发现Api多了一个External描述,意思就是扩展。获取打印的路径是:

/storage/emulated/0

其中emulated的意思是模拟器,这里会让我们产生误解,以为这是模拟器的内存空间。然后我开启了一个模拟器,同样的打印以下代码:

               //内部路径
                val dataDirectory = Environment.getDataDirectory() //data
                LogUtils.e(">>>>>>>>>>>>>", "dataDirectory:$dataDirectory")
                val downloadCacheDirectory = Environment.getDownloadCacheDirectory()//cache
                LogUtils.e(">>>>>>>>>>>>>", "downloadCacheDirectory:$downloadCacheDirectory")
                val rootDirectory = Environment.getRootDirectory() //system
                LogUtils.e(">>>>>>>>>>>>>", "rootDirectory:$rootDirectory")
                val cacheDir = context.getCacheDir()//data/data/com.penngo.test/cache
                LogUtils.e(">>>>>>>>>>>>>", "cacheDir:$cacheDir")
                val filesDir = context.getFilesDir()//data/data/com.penngo.test/files
                LogUtils.e(">>>>>>>>>>>>>", "filesDir:$filesDir")

                // 存储卡路径
                val externalStorageDirectory = Environment.getExternalStorageDirectory() //storage/sdcard0
                LogUtils.e(">>>>>>>>>>>>>", "externalStorageDirectory:$externalStorageDirectory")
                // 与context.getFilesDir(相似,删除应用时会同时删除
                val externalFilesDir = context.getExternalFilesDir(Environment.DIRECTORY_MOVIES) //storage/sdcard0/Android/data/com.penngo.test/files
                LogUtils.e(">>>>>>>>>>>>>", "externalFilesDir:$externalFilesDir")
                // 与context.getCacheDir()相似,删除应用时会同时删除
                val externalCacheDir = context.getExternalCacheDir()//storage/sdcard0/Android/data/com.penngo.test/cache
                LogUtils.e(">>>>>>>>>>>>>", "externalCacheDir:$externalCacheDir")

安卓手机实体机和模拟器打印的输出日志都是下面的日志信息:

  ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    │ main, com.fenjiread.learner.activity.TestActivity$initListeners$1.onClick(TestActivity.kt:45)
    ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
    │ args[0] = >>>>>>>>>>>>>
    │ args[1] = dataDirectory:/data
    └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2019-06-19 15:14:29.160 3699-3699/com.fenjiread.learner E/TestActivity:  
    ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    │ main, com.fenjiread.learner.activity.TestActivity$initListeners$1.onClick(TestActivity.kt:47)
    ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
    │ args[0] = >>>>>>>>>>>>>
    │ args[1] = downloadCacheDirectory:/data/cache
    └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2019-06-19 15:14:29.161 3699-3699/com.fenjiread.learner E/TestActivity:  
    ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    │ main, com.fenjiread.learner.activity.TestActivity$initListeners$1.onClick(TestActivity.kt:49)
    ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
    │ args[0] = >>>>>>>>>>>>>
    │ args[1] = rootDirectory:/system
    └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2019-06-19 15:14:29.162 3699-3699/com.fenjiread.learner E/TestActivity:  
    ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    │ main, com.fenjiread.learner.activity.TestActivity$initListeners$1.onClick(TestActivity.kt:51)
    ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
    │ args[0] = >>>>>>>>>>>>>
    │ args[1] = cacheDir:/data/user/0/com.fenjiread.learner/cache
    └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2019-06-19 15:14:29.163 3699-3699/com.fenjiread.learner E/TestActivity:  
    ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    │ main, com.fenjiread.learner.activity.TestActivity$initListeners$1.onClick(TestActivity.kt:53)
    ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
    │ args[0] = >>>>>>>>>>>>>
    │ args[1] = filesDir:/data/user/0/com.fenjiread.learner/files
    └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2019-06-19 15:14:29.168 3699-3699/com.fenjiread.learner E/TestActivity:  
    ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    │ main, com.fenjiread.learner.activity.TestActivity$initListeners$1.onClick(TestActivity.kt:57)
    ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
    │ args[0] = >>>>>>>>>>>>>
    │ args[1] = externalStorageDirectory:/storage/emulated/0
    └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2019-06-19 15:14:29.170 3699-3699/com.fenjiread.learner E/TestActivity:  
    ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    │ main, com.fenjiread.learner.activity.TestActivity$initListeners$1.onClick(TestActivity.kt:60)
    ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
    │ args[0] = >>>>>>>>>>>>>
    │ args[1] = externalFilesDir:/storage/emulated/0/Android/data/com.fenjiread.learner/files/Movies
    └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2019-06-19 15:14:29.171 3699-3699/com.fenjiread.learner E/TestActivity:  
    ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    │ main, com.fenjiread.learner.activity.TestActivity$initListeners$1.onClick(TestActivity.kt:63)
    ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
    │ args[0] = >>>>>>>>>>>>>
    │ args[1] = externalCacheDir:/storage/emulated/0/Android/data/com.fenjiread.learner/cache

总结一下:
安卓的缓存机制有5种:
1)网络缓存。依赖接口实现
2)SharePreferenced缓存,简单、方便、Key和Value对应存储,默认保存在手机内置内存中。
3)SqlLite数据库存储,原生实现比较复杂,需要熟练Sql语句。第三方GreenDao集成方便,升级需要手动的迁移之前的表。默认也是保存在手机内置内存的。
4)文件存储。这种方式区别与上面的两种方式是不是android framwork框架提供的存储方式,而是通过让存储数据实体实现Serializable接口来实现序列化到本地的文件。然后我们一般保存的路径一般都是带有External的Api,表示的是获取手机的外置内存。
比较常用的就是下面的两个缓存路径:

context.getExternalFilesDir(Environment.DIRECTORY_MOVIES)=/storage/emulated/0/Android/data/com.fenjiread.learner/files/Movies
context.getExternalCacheDir()=/storage/emulated/0/Android/data/com.fenjiread.learner/cache`

5)对于什么情况下才会用到自定义的ContentProvider,官方文档的Dev Guide是这样描述的:
如果你想要提供以下的一种或几种特性的时候你才需要构造一个ContentProvider:
你想要为其它的应用提供复杂的数据或者文件;
你想允许用户从你的应用中拷贝复杂的数据到其它的应用中;
你想要使用搜索框架来提供自定义的搜索策略。
你完全不需要ContentProvider来调用一个SQLite数据库,如果这种调用完全在你自己的应用之中。
也就是说,ContentProvider的作用是为别的应用调用本应用中的数据或者文件提供接口,而它也是唯一的跨应用数据传递的接口。如果仅仅是同一个应用中的数据传递,则完全没有必要使用到自定义的ContentProvider。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值