android 数据存储
当用户卸载app时,android系统会删除:
保存在内部存储(internal storage)的所有文件
通过
getExternalFilesDir()
方法保存在外部存储(external storage)的所有文件还有,应该手动删除缓存文件
getCacheDir()
以及定期删除不需要的文件
SharedPreference
getSharedPreferences()
- 可以有操作多个文件,通过文件名区分。可以在app的任何上下文中调用。getPreferences()
- 在activity中操作一个文件,因为取回的文件属于某个activity,所以不需要提供名称参数。在fragment中使用
1 | Context context = getActivity; |
- 如果你的activity只需要一个shared preference 文件
1 | SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); |
如果创建一个文件指定模式为
MODE_WORLD_READABLE
orMODE_WORLD_WRITEABLE
,则其他的app如若知道文件的标志符就可以访问该数据
- 写数据
1 | SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); |
- 读数据
1 | SharedPreference sharedPref = getActivity().getPreferences(Context.MODE_PRIVITE); |
File
内部存储
总是可用
默认情况下,只有你自己的app可以访问
当用户卸载app,这里的文件将被移除
当你决定用户或者其他app都不可能访问你的文件时,最好存在内部存储
外部存储
并不总是可用,用户可能会添加或移除外部存储设备
全局可读(its world-readable),所以存在这里的文件,可以在你的控制范围之外被读取
如果外部存储文件的文件位置是通过
getExternalFilesDir()
方法获取的,当用户卸载app时,系统会移除app保存的文件- 当然外部存储也分两种类型,
public files
用户和其他app可用,但当用户卸载app时,文件依然保留,例如:app拍的照片和下载的文件;private files
用户卸载app时移除文件,如:app下载的额外资源,历史媒体文件。
- 当然外部存储也分两种类型,
如果对文件的访问不做限制(restriction),允许用户(通过电脑访问)或者其他应用访问,文件存储在外部存储为好
尽管app默认会安装到内部存储,你也可以通过设置manifest文件的
android:installLocation
属性,指定app的存储位置
权限permission
- 存储到外部存储时,需要
WRITE_EXTERNAL_STORAGE
权限
1 | <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORATE" /> |
目前,app默认有读取外部存储的权限,但是将来的版本会修改。如果app需要读取外部存储,需要
READ_EXTERNAL_STORAGE
1 <uses-premission android:name="android.permission.READ_EXTERNAL_STORAGE" />
如果,你的app指定了WRITE_EXTERNAL_STORAGE
权限,那它隐含的就有了读外部存储的权限
将文件保存到内部存储
getFilesDir()
- 为你的app返回一个内部的文件夹getCacheDir()
- 为app返回一个临时存储的内部存储的文件夹。当文件不再需要时记得将他删除,使用时,给它一个合适的内存大小限制,如1mb。如果系统内存过低,会直接删除缓存文件不会给出警告
1 | // 通过构造方法创建新的file |
保存文件到外部存储
- 因为外部存储可能不可用,所以
getexternalStorageState()
判断一下外部存储状态,如果返回MEDIA_MOUNTED
,那就可用啦
1 | // checks if external storage is aailable for read and write |
尽管在外部存储的文件可以被用户或者其他应用修改,这里有两类文件(public/private files)供选择:
public files
用户和其他app都可以访问,当用户卸载该app时,文件仍旧存在,且用户可用。eg: 该app拍的照片或者下载的文件
private files
文件属于该app,且当用户卸载app时文件也被删除。尽管用户或者其他app可以通过技巧访问该文件,因为文件位于外部存储,但是文件事实上是不提供给该app以后的其他用户值的。当用户删除该app,系统将删除该app存储在外部存储的所有private directory。
eg: 该app下载的额外资源以及临时的媒体文件。
如果要在外部存储存入公共的文件,使用getExternalStoragePublicDirectory()
方法获得File
,这个方法携带一个参数指定存储文件的类型,如DIRECTORY_MUSIC
和DIRECTORY_PICRURE
1 | public File getAlbumStorageDir(String albumName) { |
在外部存储存入app的私有文件,使用getExternalFilesDir()
然后指定任何一个标示文件夹的名字。为一个使用该方式创建的文件夹被添加到你app外部存储的跟文件夹中。当用户卸载你的app时,系统删除该文件夹。
1 | public File getAlbumStorageDir(Context context, String albumName) { |
如果没有与定义的字文件夹适合你要存储的文件,你可以使用getExternalFilesDir()
方法不传入任何参数,该方法将返回你app外部存储私有文件夹的根文件夹。
查询可用空间
可以通过getFreeSpace()
hegetTotalSpace()
两个方法获取可用空间和总空间。
但是,系统不保证你可以写通过getFreeSpace()
获得可用容量大小的东西。如果该方法返回的空间比你要存储文件的size大个几m,或者文件系统容量小于总容量的90%,或许是可以安全执行的。除此之外,你也许不应该存储。
当你存储文件的时候,你不确定具体需要的存储空间,此时:你不需要请求可用的存储空间,可以通过
try catch
来处理和捕获io异常。eg:将png文件存储为jpeg,改变文件的编码,在存储之前不知道文件的具体大小。
删除文件
直接的删除文件的方法 to have the opened file reference, 调用delete()
删除自己
1 | myFile.delete(); |
如果文件保存在内部存储,你需要当前的Context
对象调用deleteFile()
方法删除
1 | myContext.deleteFile(fileName); |
Database
1 | # TODO |