安卓碎片化的问题,由来已久,此次来看一下文件储存碎片化的问题。到底要怎么去正确选择和管理文件存储呢?java
Android手机一直以来被人诟病越用越卡,越用存储空间越少,常常有要靠各类清理app清理垃圾,到最后不得对手机进行双清,缘由除了硬件老化和Android的底层实现问题以外,开发者对文件管理的忽视制造出大量没法清理的“垃圾”也是形成手机卡慢的缘由之一。android
Android的开放性给了开发者巨大的自由度,但自由不是让咱们滥用权限和随意开发的借口,每个开发者都应该注重细节,连曾经一片混乱的第三方推送都开始统一整合规范化了,若是你还在随意开发,不如如今开始,注重细节,提升用户的Android手机体验?api
总所周知,Android手机存储分为两个部分:内部存储和外部存储,内部存储通常是手机自带的存储空间,外部存储指外插SD卡提供的存储空间;随着手机发展,这两个存储的定义又有了一些些变化,新的手机再也不有外插SD卡的概念,采起了内置闪存(eMMC、UFS等)的方式,因此内部存储和外部存储在新的Android手机上已经在同一个硬件上了。但为了兼容旧设备和让用户获得更好的体验,咱们仍然须要管理好手机上内外存储的使用。缓存
作过文件相关管理的同窗应该都曾经被android众多的文件api搞得一片混乱过,如今来理一理.微信
我把应用操做的文件存储位置分为三个部分:app
咱们有两种api去获取这三个部分的存储位置,它们分别归属于Context和Environment。工具
Context是应用的上下文,它用来获取与应用相关的文件目录,能够获取应用私有和应用公有目录,经常使用的api有(后面是所对应的路径):spa
1. Context#getCacheDir() /data/user/0/cn.appname.xxx/cache
2. Context#getDir("spanner",MODE_PRIVATE) /data/user/0/cn.appname.xxx/app_spanner
3. Context#getFileDir() /data/user/0/cn.appname.xxx/files
3. Context#getExternalCacheDir() /storage/emulated/0/Android/data/cn.appname.xxx/cache
4. Context#getExternalFilesDir(Environment.DIRECTORY_PICTURES) /storage/emulated/0/Android/data/cn.appname.xxx/files/Pictures
Context#getExternalFilesDir(null) /storage/emulated/0/Android/data/cn.appname.xxx/files
5. Context#getExternalMediaDirs() /storage/emulated/0/Android/media/cn.appname.xxx
复制代码
前两个是应用内部存储私有目录,后面4个都是应用外部存储私有文件目录。 注意:/data/user/0/ 等同于 /data/data/code
Environment和应用无关,它用于获取公有存储位置的文件目录,经常使用的api有:cdn
1. Environment#getExternalStorageDirectory() /storage/emulated/0
2. Environment#getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) /storage/emulated/0/DCIM
Environment#getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) /storage/emulated/0/Pictures
3. Environment#getDataDirectory() /data
4. Environment#getDownloadCacheDirectory() /data/cache
5. Environment#getRootDirectory() /system
复制代码
到底何时要用什么api呢?
应用私有目录由Context获取控制,分为内部存储和外部存储,内部存储不须要申请文件读写权限也可以使用,外部存储须要权限(getetExternalCacheDir() 和 getExternalFilesDir() 这两个方法从4.4以后再也不须要读写权限)。用户对app进行数据清理或卸载能够清理外部存储和内部存储下的全部文件目录。
内部存储
内部存储的文件夹其余应用和用户没法直接访问,能够用于存放敏感数据。
getCacheDir()
getFileDir()
getDir(String name,int mode)
外部存储
在Android Q以前其余应用是能够访问修改外部存储的应用私有目录的,这个要注意。
使用外部存储以前必定要检查外部存储是否可用,由于旧设备不必定会有外部存储,新手机也不必定会给你读写权限,就算用户不给你权限,你的app也要运行啊,否则就不用你的了。
public static boolean isSDCardEnable() {
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
}
复制代码
getExternalCacheDir()
getExternalFilesDir(String type)
getExternalMediaDirs()
获取公有目录要使用Environment的Api,它返回的目录全都是共享的公有目录。形成Android手机文件存储混乱的罪魁祸首!为数众多的无责任开发者在这里胡乱建立文件夹,乱起名、乱放文件,普通用户根本没法判断哪些文件夹、文件是有用的,卸载app以后留下庞大的没法清理的垃圾文件,致使手机空间不足。因而它们在Android Q被废弃了,可是Q以前仍是能好好使用的,我认为要开始减小使用它们,更多地使用Context下的私有目录API。
getExternalStorageDirectory()
getExternalStoragePublicDirectory(String type)
使用频率极高的api,返回在根目录下的名为type的文件夹,我把它分为两种用法:一种是传入Environment的DIRECTORY常量再建立子目录使用;一种是传入appPackageName或者易被识别归属的名称建立子目录使用。前者会比较通用,内容能够被各类工具app搜索发现(包括微信);后者算是私用,能够存放不跟随app生命的文件,即卸载后也能够保留。
Environment.DIRECTORY_DCIM是手机的相册,这个文件夹都是系统相关的app在用,存放相机拍摄的图片,手机截图之类的,不推荐开发者使用这个文件夹,避免混乱。值得一提的是淘宝有在使用这个文件夹,用于保存它的商品分享截图,这个位置的确能够避免被微信封杀~哈哈
Environment.DIRECTORY_PICTURES用于存放各类“正式的”图片,强烈建议在这里建立文件夹存放你想要被用户发现的图片,而且微信会扫描这个文件夹,让你的图片更容易分享。不过还。
Environment.DIRECTORY_DOWNLOADS能够用于存放app更新的apk等下载资源。
其余几个比较少用就不介绍了。
上面提到Environment的两个公有目录经常使用API在Android Q被废弃了,应用存储功能沙箱化,文件存放到沙箱外面要使用 DocumentFile,共享媒体文件要使用MediaStore进行,详细的适配已有其余开发者分享出来了,推荐一下这篇:feng.moe/archives/47…
我很喜欢的承香墨影也出了篇适配指南,内容更加详细:mp.weixin.qq.com/s/aiDMyAfAZ…
最后说一下几个重要的事:
此次的分享到这里,但愿看完这篇文章以后可以让你更了解如何管理手机文件夹。