你真的知道APP缓存目录的内幕吗

Android 缓存


大家开发Android的APP的时候,大都会用三方的图片加载框架吧,eg:Glide,Pacasio等。有时候配置这些图片加载框架的时候我们就需要自己写一个图片缓存的本地存储地址。在Android手机里面,存储的位置分为两类,一类是Internal Storage,即内部存储,另外一类是External Storage,即外部存储。比较老的手机,有一个手机内部存储,还有一个SD卡存储,就是分别对应这两种存储位置,因为以前的SD卡是可以扩展的,即可拆卸的,所以可以用是否可拆卸作为内外存储的分类标准。但是现在最新的设备,比如小米、锤子、华为等,都取消了可拆卸的SD卡,直接与机身焊接在一起,分为16G、32G版本,所以现在内外存储的分类不再以是否可拆卸作为标准,而是以下面的几方面作为新的标准:

首先我们分别介绍下Android中几种存储方式的不同之处和应用。

一、各自的存储特点

1.内部存储

  • 总是可用的
  • 这里的文件默认是只能被你的app所访问的
  • 当用户卸载你的app的时候,系统会把internal里面的相关文件都清除干净
  • Internal是在你想确保不被用户与其他app所访问的最佳存储区域。

2.外部存储

  • 并不总是可用的,因为用户可以选择把这部分作为USB存储模式,这样就不可以访问了。
  • 是大家都可以访问的,因此保存到这里的文件是失去访问控制权限的。
  • 当用户卸载你的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。
  • External是在你不需要严格的访问权限并且你希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。

二、文件位置和相关API

0. 检查介质可用性

在使用外部存储执行任何工作之前,应始终调用 getExternalStorageState() 以检查介质是否可用。介质可能已装载到计算机,处于缺失、只读或其他某种状态。 例如,以下是可用于检查可用性的几种方法:

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

1.内部存储

  • getFileDir() 通过此方法可以获取到你的APP内部存储的文件,路径为/data/data/pacgage_name/files
  • getCacheDir() 通过此方法可以获取到你的APP内部存储的文件,路径为/data/data/package_name/cache
  • openFileOutput() 通过此方法,我们可以获取到一个输出流,输出流的保存路径是/data/data/package_name/files ,和getFileDir()的路径一致

2.外部存储

2.1 私有存储

  • Context.getExternalCacheDir()
  • Context.getExternalFilesDir()

创建的私有文件的地址是/sdcard/Android/date/package_name下面,Android文件夹是隐藏文件夹,用户无法操作。

如果我们想缓存图片等比较耗空间的文件,推荐放在getExternalCacheDir()所在的文件下面,这个文件和getCacheDir()很像,都可以放缓存文件,在APP被卸载的时候,都会被系统删除,而且缓存的内容对其他APP是相对私有的。 2.2 公有存储

  • Environment.getExternalStorageDirectory()
  • Environment.getExternalStoragePublicDirectory()

你的APP产生的文件不需要隐藏,即对用户是可见的,那么你可以把文件放在外部的公共存储文件下面。这个方法不是Context的方法,而是Environment的两个方法,第一个方法获取到的其实是外部存储的根目录,而第二个方法获取到得则是外部存储的公共目录。其实在访问权限上是没有区别的,不同点是getExternalStoragePublicDirectory()在运行的时候,会需要你带有一个特定的参数来指定这些public的文件类型,以便于与其他public文件进行分类。 例如,以下方法在公共图片目录中创建了一个用于新相册的目录:

public File getAlbumStorageDir(String albumName) {
    // Get the directory for the user's public pictures directory.
    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

4.其他实用API

  • getFilesDir() 获取在其中存储内部文件的文件系统目录的绝对路径。
  • getDir() 在您的内部存储空间内创建(或打开现有的)目录。
  • deleteFile() 删除保存在内部存储的文件。
  • fileList() 返回您的应用当前保存的一系列文件。

三、清除数据、清除缓存的区别

清除数据主要是清除用户配置,比如SharedPreferences、数据库等等,这些数据都是在程序运行过程中保存的用户配置信息,清除数据后,下次进入程序就和第一次进入程序时一样。而缓存是程序运行时的临时存储空间,它可以存放从网络下载的临时图片,从用户的角度出发清除缓存对用户并没有太大的影响,但是清除缓存后用户再次使用该APP时,由于本地缓存已经被清理,所有的数据需要重新从网络上获取。为了在清除缓存的时候能够正常清除与应用相关的缓存,请将缓存文件存放在getCacheDir()或者 getExternalCacheDir()路径下。

存储选项-Android官方文档 Android中系统设置中的清除数据究竟会清除哪些数据

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Flutter知识集

Android原生项目集成Flutter Module

成功执行后,会在.android/Flutter/build/outputs/aar/目录下,创建一个flutter-debug.aar的包文件

2.2K0
来自专栏白驹过隙

Socket编程回顾,一个最简单服务器程序

2293
来自专栏openshift持续集成

jenkins邮件插件中的内容参数设置

众所周知,Jenkins默认提供了一个邮件通知,能在构建失败、构建不稳定等状态后发送邮件。但是它本身有很多局限性,比如它的邮件通知无法提供详细的邮件内容、无法定...

9348
来自专栏文大师的新世界

8. 遇到不可抗力的自然灾害

之前提到过尽量不要改名,涉及到的改动比较大,会遇到各种不知名错误,趁着本次改动详细记录一下:

673
来自专栏腾讯移动品质中心TMQ的专栏

像 google 一样测试系列之六: 实战篇

本文主要介绍 google 一样测试系列的实战内容,Mock 和反射执行,会穿插在各章节中,因此不单独成节了。

1651
来自专栏用户3030674的专栏

Android文件各种存储路径的比较

应用内部存储空间(数据文件私有)文件存储到这个路径下,不需要申请权限,当应用被卸载的时候,目录下的文件会被删除。 需要注意的是,这个文件的目录和应用的存储位...

2971
来自专栏北京马哥教育

DNS从入门到管理(一)

DNS概述 DNS(Domain Name System,域名系统),域名和IP地址相互映射的一个分布式数据库,通过主机名,最终得到该主机名对应的IP地址的过程...

6536
来自专栏漫漫前端路

前端安全知识

xss: 跨站脚本攻击(Cross Site Scripting)是最常见和基本的攻击 WEB 网站方法,攻击者通过注入非法的 html 标签或者 javasc...

1152
来自专栏Java编程技术

Druid连接池原理学习

(1)、 如果设置了maxWait或者构造函数参数传入的为true,则创建的ReentrantLock为公平锁,否者为非公平锁 (2)、 如果设置了initi...

1.8K1
来自专栏linux系统运维

原 添加自定义监控项目,配置邮件告警,测

2093

扫码关注云+社区

领取腾讯云代金券