一、Android中 getCacheDir()、getFilesDir()、getExternalFilesDir()、getExternalCacheDir()区别
应用程序在运行过程中如果需要在手机上保存数据,一般把数据保存在SDCard中,大部分应用会直接在SDCard的根目录下创建一个文件夹,然后把数据保存在该文件夹中,但应用卸载后数据还是会保留在SDCard中,解决方法:
通过Context.getExternalFilesDir()方法可以获取到 SDCard/Android/data/包名/files/ 目录
通过Context.getExternalCacheDir()方法可以获取到 SDCard/Android/data/包名/cache/目录
使用上面的方法,应用卸载后,SDCard/Android/data/包名/ 目录下的所有文件都会被删除。而且上面两个目录对应手机设置里面的“清除数据”与“清除”缓存选项,如果要保存下载的内容就不要放在这两个目录下。
当SD卡存在或者SD卡不可被移除的时候,就调用getExternalCacheDir()方法来获取缓存路径,否则调用getCacheDir()方法来获取缓存路径,这两种方式的缓存都会在应用卸载后被系统清理掉,而如果是另行在SD卡上新建的缓存文件夹,是不会随应用的卸载而被清除掉。
Context.getCacheDir() 获取/data/data/包名/cache目录 (应用安装目录下的cache文件)
Context.getFilesDir() 获取/data/data/包名/file目录 (应用安装目录下的file文件)
Context.getExternalFilesDir() 获取SDCard/Android/data/包名/files/目录
Context.getExternalCacheDir() 获取SDCard/Android/data/包名/cache/目录
Environment.getExternalStorageDirectory() 获取SD卡根目录
Environment.getExternalStoragePublicDirectory(Environment.xxx) 获取SD卡公共目录
比如:Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); 目录为:mnt/sdcard/Pictures;
总结:
相同点:
1、相同点:都可以做app缓存目录。
2、app卸载后,两个目录下的数据都会被清空。
不同点:
1、目录的路径不同。前者的目录存在外部SD卡上的。后者的目录存在app的内部存储上。
2、前者的路径在手机里可以直接看到。后者的路径需要root以后,用Root Explorer 文件管理器才能看到。
获取缓存地址的方法:
需要注意的事项:
由于context.getExternalCacheDir() 的目录存在外部SD卡上的,所以在使用这个方法的时候要判断外部SD卡的状态是否可用。
public String getDiskCacheDir(Context context) {
String cachePath = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|| !Environment.isExternalStorageRemovable()) {
cachePath = context.getExternalCacheDir().getPath();
} else {
cachePath = context.getCacheDir().getPath();
}
return cachePath;
}
二、Android目录获取
(1)/data/data/package_name/...(该目录只对应用可见,如果手机没有root,用普通权限的adb也看不了,该目录用来存储和应用周期相关的文件,随应用的卸载一起删除),相关子目录如下:
1、/data/data/package_name/shared_prefs/(用来存储SharedPreference,对应函数为:getSharedPreferences(String fileName,int mode))
2、/data/data/package_name/databases/(用来存储数据库DB,对应函数:getDatabasePath())
3、/data/data/package_name/app_webview和/data/data/package_name/xxxwebviewcachexxx(用来存储应用内置webview所产生的cache和cookies,该目录由于android版本不同名字和位置也可能不同)
4、/data/data/package_name/lib(用来存储该应用的.so静态文件)
5、/data/data/package_name/cache(通过函数getCacheDir()获取)
6、/data/data/package_name/files(该目录可通过函数getFilesDir()获取,openFileInput()和openFileOutput()函数也是在该目录下操作文件,fileList()函数是用来列出该files目录下的所有文件,deleteFile(String name)用来删除该files目录下的文件)
7、/data/data/package_name/xxx(这个目录下还能够创建xxx子目录,使用方法就是getDir(String name,int mode),参数中的name就是需要在该目录下创建的子目录名字)
getPackageCodePath() = /data/app/package_name.apk;
getPackageResourcePath() = /data/app/package_name.apk。
注:以上函数没有明确指定的都是使用 Context 调用。
(2)SD卡下的目录
SD卡下分为应用的私有目录和共有目录,SD卡不可用时这两个目录都是无效的。私有目录的生命周期也是和应用挂钩的,卸载之后就会被删除,共有目录不会随着应用的卸载而删除。
可以通过 Environment.getExternalStorageState() 函数来获取 SD 卡的挂载状态,当该函数返回mounted的时候,代表SD卡可用。
注意:SD卡使用时需要注册相关权限:<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>
1、SD卡私有目录(该目录下的文件卸载应用之后会自动删除)
/sdcard/Android/data/package_name/
/sdcard/Android/data/package_name/files/(该目录可用 getExternalFilesDir(String type)获取)
Context.getExternalFilesDir(""): /storage/emulated/0/Android/data/package_name/files
Context.getExternalFilesDir("test"): /storage/emulated/0/Android/data/package_name/files/test
Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES): /storage/emulated/0/Android/data/package_name/files/Pictures
Android/data/com.android.framework/cache/(该目录可用getExternalCacheDir()获取)
/sdcard/Android/obb/package_name/
需要注意的是,obb 目录也可能不存在,一般游戏 APP 会将游戏相关的数据包放到这个目录下。
该目录的的相关函数简单只有两个:getObbDirs() 和 getObbDir(),前者调用之后会自动生成该目录,后者在插入外置存储卡之后会在前者的基础上另外返回外置存储卡的obb目录
2、SD 卡共有目录
该目录下的文件卸载应用之后还会留存,所以为了SD卡的整洁度,不要随便在SD卡的根目录下面创建文件,最好以应用名字创建一个目录,所有的需要卸载之后留存或者需要给其他应用共享的文件都放到该目录下,不要在根目录下创建文件,还有一个公司的多个应用最好共享一个目录。
/sdcard/(any_folder_name)
Environment.getExternalStorageState()(这个函数用来获取SD卡的挂载状态,如果传入参数path则是获取该路径的的挂载状态)
Environment.getExternalStorageDirectory()(该函数用来返回SD卡的根目录)
Environment.getDownloadCacheDirectory()(该函数用来返回SD卡的下载缓存目录)
Environment.getDataDirectory()(该函数用来获取用户的数据目录)
Environment.getExternalStoragePublicDirectory(String type)(该函数用来根据类型返回相关目录,类型为 Environment 的一些变量,传入的类型参数不能是 null,返回的目录路径有可能不存在,所以必须在使用之前确认一下,没有就创建该目录)
Environment.getRootDirectory()(该函数用来返回根 System 目录,只挂载为只读)
配置访问外部存储的权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>