关于Android数据缓存目录分析
- 结论
- 1、安卓分区
- 2、需求分析
- 3、常用方法
- 4、特点
结论
isExternalStorageEmulated(file) ==true
无论存储数据大小使用context.getFilesDir()/context.getCacheDir()。
isExternalStorageEmulated(file) ==false
根据下面介绍具体使用。
1、安卓分区
通常有以下分区(可以使用adb shell 的df命令查看具体分区详情)
分区 | 作用 |
system | rom数据 |
data | 我们装apk的地方(data/app) |
cache | 缓存分区,存储一些系统缓存,擦除不影响app数据。 |
media | 挂载sd卡或内部存储。 |
… |
注:通常情况下data分区和内部存储分区为同一个分区(感觉像同一分区挂载到不同目录)。当然也存在data分区和内部存储分区分开的情况(比如小米2/2s分为系统存储和内部存储)。
2、需求分析
主要分析app缓存数据及下载数据需要存放的位置。为了兼容大部分手机考虑进行如下分配:
数据量大 | 数据量小 |
media分区 | data分区 |
具体使用分类:
数据量大 | 数据量小 |
音视频下载、文件下载等 | 图片缓存、文件缓存等 |
对应使用方法:
isExternalStorageEmulated(file) ==false
数据量大 | 数据量小 |
Environment.getExternalStorageDirectory() | context.getFilesDir() |
context.getExternalFilesDir(dir) | context.getCacheDir() |
context.getExternalCacheDir() |
isExternalStorageEmulated(file) ==true
数据量大 | 数据量小 |
context.getFilesDir() | context.getFilesDir() |
context.getCacheDir() | context.getCacheDir() |
数据量小的情况:
例如:图片缓存类数据,由于数据缓存比较小,并且大部分三方图片加载框架可以设置图片缓存大小,所以此类数据可以存放在/data分区下,一般存放于/data/data/cache目录下(实际为/data/user/0//cache)
数据量大的情况:
例如:音视频文件下载,由于数据量比较大,假如不需要用户直接使用的情况下推荐使用context.getExternalFilesDir(dir)方法,数据存储到内存根目录.android目录对应的包名中,此时app卸载时,数据会同时卸载。如果提供用户直接导出的情况下,可以考虑使用Environment.getExternalStorageDirectory()方法,同时媒体类文件也容易被播放器发现。
3、常用方法
区别 | 方法 | 备注 |
external storage 外部存储 | Environment.getExternalStorageDirectory() | /mnt/sdcard/ (6.0后写入需要用户授权) |
external storage 外部存储 | context.getExternalFilesDir(dir) | /mnt/sdcard/Android/data/< package name >/files/… |
external storage 外部存储 | context.getExternalCacheDir() | /mnt/sdcard//Android/data/< package name >/cach/… |
Internal storage内部存储 | context.getFilesDir() | /data/data/< package name >/files/… |
Internal storage内部存储 | context.getCacheDir() | /data/data/< package name >/cach/… |
4、特点
方法 | 特点 |
Environment.getExternalStorageDirectory() | 1、路径可能不存在,需要通过getExternalStorageState()获取外部内存挂载状态。2、非安全的,被所有应用共享。3、以sdcard目录形式挂载。实际可以是sdcard或者内部存储。4、用户隔离的,多用户情况下,暂不涉及,参考UserManager。5、应用卸载不会自动删除。6、需要Manifest申请权限,6.0以上需要动态申请权限。版本不同获取的路径可能不同。 |
context.getExternalFilesDir(dir) | 1、路径可能不存在,需要通过getExternalStorageState()获取外部内存挂载状态。2、非安全的,可以被其他应用访问但需要读写权限。3、用户隔离的,多用户情况下,暂不涉及,参考UserManager。4、应用卸载会被删除。5、4.4之后不需要申请权限。 |
context.getExternalCacheDir() | 1、同上。2、API17以上支持自动清理cache,但有个前提条件是isExternalStorageEmulated() == true。 |
context.getFilesDir() | 1、安全。2、应用卸载会自动删除。3、使用openFileoutPut()/openFileinPut()方便数据操作。4、不需要申请权限。 |
context.getCacheDir() | 1、安全。2、应用卸载自动删除。3、不需要申请权限。4、会自动清理缓存,在需要空间的时候。5、可以配置清理规则,默认先清理旧数据。6、8.0之后会有缓存配额,超过优先清除。配额会根据用户的使用情况去调整。7、不需要申请权限。 |
注:isExternalStorageEmulated() == true(表示挂载有虚拟外部存储,这种情况就是说data分区和内部虚拟存储为同一分区,若两者分开应该为false,暂无法验证)