在应用开发中,我们经常会需要保存文件,常用的有那么几个办法,但是不知道大家在使用的过程中有没有如下几个疑问:
(1)我保存的sharedPrefs和数据库到底在哪,怎么找不到?
(2)怎么判断设备有没有sdCard呢?
(3)我想缓存一些文件,应该使用哪个方法,被保存在哪里?
(4)我想保存一些文件,有的可以让别的APP访问(例如:App拍的照片可以让其他图片APP访问),有的只能自己的APP使用,那该怎么办?
(5)当用户清除缓存,清除数据,甚至删除APP的时候,我所保存在各个地方的文件会有怎样的“下场”?
不知道你们是否很清楚的知道上面的答案呢?让我们来一起探索下吧。
Android存储分类
Android存储分为两种:Internal storage(内存) 和External storage(外部存储)
Internal storage(内存)
相信大家都不陌生,买手机的时候都会关注这个指标。跟外部存储动辄16G,32G比起来,内存真的是小的可怜,2,3G的空间还要装上系统和各种应用。所以导致内存的空间是寸土寸金啊。那什么样的文件应该保存在这“珍贵”的内存上呢,请看以下几点:
(1)你想确保这些文件总是可用的,比如数据库或者配置文件;
(2)只能被你的APP所访问的文件(除非在root情况下,不然用户也无法在找到该文件);
(3)卸载你的APP时,相关文件需要删除
如果满足以上几点,那你就可以放心的把文件保存在内存里吧。让我们来看看Android提供的保存在内存里的方法(当然你可以直接输入地址):
Context.getCacheDir()
该方法的得到的路径是:/data/data/App包名/cache
通过方法名就能得知该路径下保存的是APP在内存中的缓存文件,请合理控制缓存文件的大小,并且在不需要的时候请及时删除。另外,在系统内存空间不够时,也会优先删除缓存文件,所以一些影响着APP能否正常使用的文件请不要放在该目录下。
(NOTE: /data/data需要在手机root的情况下才能看到)
Context.getFilesDir()
该方法的得到的路径是:/data/data/App包名/files
该目录可以保存一些只能被自己APP访问的文件。
另外SharedPreference和数据库也保存在/data/data/App包名/中对应的目录下。
External storage(外部存储)
说到手机最常用的外部存储,那就是sdCard了,sdCard的容量相比内存那就大了好多了,所以我们就可以大胆任性的往里面存存存。等等!
要是手机没sd卡那不就会出错了吗?说的没错,外存跟内存不一样,它并不一定总是存在的(比如没有sd卡),所以在我们想用的时候就必须判断下是否可用外存:
//判断是否可用sd卡存储
public boolean isSdCardUseable(){
return (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
|| !Environment.isExternalStorageRemovable());
}
该方法判断了外部存储的状态,MEDIA_MOUNTED表示已挂载;只有当返回true时,即当外存已挂载或者不可被移除时,sd卡可用。
光光判断是否可用还不够,由于Android有一套权限机制,所以当我们想操作外部存储,必须在AndroidManifest中获得权限:
(1)并不总是可用的(从上面你应该看出来)
(2)保存在这里的文件,App将失去访问控制权限,也就意味着所有的人都能看到文件(这与内存相反)
让我们来看看Android提供的保存在外部存储里的方法(当然你可以直接输入地址):
Context.getExternalCacheDir()
该方法得到的路径是:/storage/sdcard0/Android/data/App包名/cache
该方法是保存在外部存储上的缓存,可以被其他APP和用户访问,当你清除APP缓存的时候,毫无疑问它也会被清除掉。
Context.getExternalFilesDir(String type)
该方法得到的路径是:/storage/sdcard0/Android/data/App包名/files/type对应的文件夹
(Note:如type是Environment.DIRECTORY_DOWNLOADS时,type对应的文件夹名是Download)
该方法需要你设置一个目录参数类型,它可以确保目录文件被系统正确对待,如PICTURE会被系统认为是图片,当App被卸载时,该目录也会被删除。
Environment.getExternalStorageDirectory()
该方法得到的路径是:/storage/sdcard0
该方法与上面的方法不同,是Environment的方法,与上面对比可得知,它与App无关,是直接保存在sd卡的目录下的,这样即使删除App,文件也依然存在。
Environment.getExternalStoragePublicDirectory(String type)
该方法得到的路径是:/storage/sdcard0/type对应的文件夹
这是一个公开的带目录参数的方法,它可以确保目录文件被系统正确对待,如PICTURE会被系统认为是图片,它与App无关,
是直接保存在sd卡的目录下的,这样即使删除App,文件也依然存在。
好了,了解了这么多,我们可以来试着解决一开始的问题了。
(1)我保存的sharedPrefs和数据库到底在哪,怎么找不到?
答:sharedPreference 和数据保存在/data/data/包名/对应的目录下。
(2)怎么判断设备有没有sdCard呢?
答:当(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) || !Environment.isExternalStorageRemovable());返回值为trues时。
(3)我想缓存一些文件,应该使用哪个方法,被保存在哪里?
答:当你想缓存的文件不想被其他App访问或者被用户可见时,用
Context.getCacheDir() ---------> /data/data/包名/cache目录下;
当缓存文件可以被其他App访问或者被用户可见时,用
Context.getExternalCacheDir() ----------> /storage/sdcard0/Android/data/包名/cache目录下。
(4)我想保存一些文件,有的可以让别的APP访问(例如:App拍的照片可以让其他图片APP访问),有的只能自己的APP使用,那该怎么办?
答:保存可让别人访问的文件,请保存在外部存储中,可用
Context.getExternalCacheDir() -----------> /storage/sdcard0/Android/data/包名/cache目录下;
Context.getExternalFilesDir(String type)-----------> /storage/sdcard0/Android/data/包名/files/type对应的文件夹;
Environment.getExternalStorageDirectory() ----------->/storage/sdcard0
Environment.getExternalStoragePublicDirectory(String type) ------------->/storage/sdcard0/type对应的文件夹
保存只能自己访问的文件,请保存在内存中,可以
Context.getCacheDir() ------------>/data/data/App包名/cache
Context.getFilesDir()------------>/data/data/App包名/files
(5)当用户清除缓存,清除数据,甚至删除APP的时候,我所保存在各个地方的文件会有怎样的“下场”?
答:点击清除缓存,带有/data/data/包名/cache/ 和 /storage/sdcard0/Android/data/包名/cache/ 下的文件会被清除,例如:
Context.getCacheDir() ---------> /data/data/包名/cache目录下;
Context.getExternalCacheDir() ---------> /storage/sdcard0/Android/data/包名/cache目录下;
点击清除数据,带有/data/data/包名/ 和 /storage/sdcard0/Android/data/包名/ 下的文件夹会被清除,例如:
Context.getCacheDir() ---------> /data/data/包名/cache目录下;
Context.getExternalCacheDir() ---------> /storage/sdcard0/Android/data/包名/cache目录下;
Context.getFilesDir()---------->/data/data/App包名/files
Context.getExternalFilesDir(String type)-----------> /storage/sdcard0/Android/data/包名/files/type对应的文件夹;
删除App,会删除/data/data/包名 和 /storage/sdcard0/Android/data/包名 文件夹。
PS:这是本人看了这么久博客第一次真正意义上的自己写,顿时发觉以前写博客真是件不容易的事,懂和能写出来完全是两码事。。。写了好几个小时好不容易憋出来了,排版啥的也都不大会,大家将就着看吧。如果能帮助到你,那我很开心;如果你能帮助到我,那我更开心