关于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,暂无法验证)