参考谷歌官方文档 关于数据保存的说明进行摘要概述 原文地址参考链接地址:
谷歌官方数据保存说明 主要分为三种方式:
一、键值对SharedPreferences
键值对的缓存方式比较适合相对较小的键值集合,有两种创建或访问共享文件的方法:getSharedPreferences() 与getPreferences()
这里不对具体的使用方式做说明,主要关注不同点
getSharedPreference() 可以在整个应用内使用任意的Contex调用 适用于应用内部有多处需要读写同一个缓存文件 比如:SharedPreferencessharedPref=context.getSharedPreferences(getString(R.string.preference_file_key),Context.MODE_PRIVATE);
getPreferences() 只属于单独的某个activity,该方法会检索属于该activity的默认共享文件,不用提供名称 比如:SharedPreferencessharedPref=this.getPreferences(Context.MODE_PRIVATE);
注意:如果创建带MODE_WORLD_READABLE或MODE_WORLD_WRITEABLE的共享首选项文件,那么知道文件标识符 的任何其他应用都可访这些缓存数据。实际开发中使用最频繁的还是context.getSharedPreferences("file name",Context.MODE)
二、文件保存(IO操作)
File对象适合按照从开始到结束的顺序不跳过地读取或写入大量数据。 例如,它适合于图像文件或通过网络交换的任何内容。
先看看谷歌对内部存储与外部存储的说明:
所有 Android 设备都有两个文件存储区域:“内部”和“外部”存储。这些名称在 Android 早期产生,当时大多数设备都提供内置的非易失性内存(内部存储),以及移动存储介质,比如微型 SD 卡(外部存储)。一些设备将永久性存储空间划分为“内部”和“外部”分区,即便没有移动存储介质,也始终有两个存储空间,并且无论外部存储设备是否可移动,API 的行为均一致。以下列表汇总了关于各个存储空间的实际信息。
内部存储:
它始终可用。
默认情况下只有您的应用可以访问此处保存的文件。
当用户卸载您的应用时,系统会从内部存储中删除您的应用的所有文件。
当您希望确保用户或其他应用均无法访问您的文件时,内部存储是最佳选择。
外部存储:
它并非始终可用,因为用户可采用 USB 存储的形式装载外部存储,并在某些情况下会从设备中将其删除。
它是全局可读的,因此此处保存的文件可能不受您控制地被读取。
当用户卸载您的应用时,只有在您通过getExternalFilesDir()将您的应用的文件保存在目录中时,系统才会从此处删除您的应用的文件。
对于无需访问限制以及您希望与其他应用共享或允许用户使用电脑访问的文件,外部存储是最佳位置。
如果只有读取外部存储操作只需要加入权限
1. 将文件保存在内部存储
以下两种方法可以获取到当前应用File内部存储目录:
getFilesDir() 返回当前应用内部目录的File
getCacheDir() 返回当前应用临时缓存目录的File
因为该方法使用的是手机内存空间,使用该方法我们要注意:必须合理控制改缓存目录文件大小,比如1MB,android系统会在内存不足时,直接将文件删掉!
在内部存储中创建文件:
File file = new File(context.getFilesDir(),filename);
或者调用openFileOutput()写入文件流:
String filename = "myfile";
String strinig = "hello world!";
FileOutputSream outputStream;
try{
outputStream = openFileOutput(filaname,Context.MODE_PRIVATE);
outputStream = write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
或者使用createTempFile() 从URL中提取文件 缓存到内部存储中:
public File getTempFile(Context context,String url) {
File file;
try {
String fileName = Uri.parse(url).getLastPathSegment();
file = FIle.createTempFile(fileName,null,context.getCacheDir());
}catch (IOException e) {
//Error while creating file
}
return file;
}
注意:您的应用的内部存储设备目录由您的应用在Android 文件系统特定位置中的软件包名称指定。在技术上,如果您将文件模式设置为可读,另一个应用可以读取您的内部文件。 但是,另一个应用也需要知道您的应用的软件包名称和文件名。 其他应用无法浏览您的内部目录并且没有读写权限,除非您明确将文件设置为可读或可写。 只要您为内部存储上的文件使用MODE_PRIVATE, 其他应用便从不会访问它们
2.将文件保存在外部存储
访问外部存储之前必须先检查一下读写性:
/*Checks if external storage is available for read and write*/
public boolean isExternalStoreageWritable() {
String state = Environment.getExternalStorageState();
if (Envirionment.MEDIA_MOUNTED.equals(state)){
return true;
}
return false;
}
/*Checks if external strorage is available to at least read*/
publi boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state){
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
return true;
}
return false;
}
尽管外部存储可被用户和其他应用进行修改,但您可在此处保存两类文件:
公共文件
应供其他应用和用户自由使用的文件。 当用户卸载您的应用时,用户应仍可以使用这些文件。
例如,您的应用拍摄的照片或其他已下载的文件。
私有文件
本属于您的应用且应在用户卸载您的应用时删除的文件。尽管这些文件在技术上可被用户和其他应用访问(因为它们在外部存储上),它们是实际上不向您的应用之外的用户提供值的文件。当用户卸载您的应用时,系统会删除应用外部专用目录中的所有文件。
例如,您的应用下载的其他资源或临时介质文件。
读写外部存储上的公共文件使用 getExternalStoragePublicDirectory(),支持系统文件类别比如
DIRECTORY_MUSIC或DIRECTORY_PICTURES:
public File getAlbumStorageDir (String albumName) {
//Get the directory for the user's public pircture directory
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES),albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG,"Directory not created");
}
return file;
}
如果保存我们的应用专用文件,调用getExternalFilesDir()获取文件目录 并传递目录类型参数,通过这个方法创建的目录会被封装到我们的应用所有外部存储文件的父目录下,当应用被卸载时,这个父目录下的文件都会被删除。例如,可以使用如下方法创建个人相册:
public File getAlbumStorageDir(Context context,String albumName) {
//Get the directory for the app's private pictures directory.
File file = new File(context.getExternalFilesDir(
Environment.DIRECORY_PICTURES),albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG,"Directory not created");
}
return file;
}
如果没有定义子目录的名称,可以调用getExternalFilesDir()并传递null,返回的是外部存储上我们应用的专用目录的根目录。切记,getExternalFilesDir()创建的目录在应用卸载时会被删除
不管是用getExternalStoragePublicDirectory()操作共享文件还是用getExternalFilesDir()操作应用专用文件,使用DIRRECTORY_PICTURES 常数参数对应的目录非常重要,这些目录可以确保系统正确处理文件。例如,保存在DIRECTORY_RINGTONES中的文件有系统介质扫描程序归类为铃声,而不是音乐。
3.查询可用空间
如果知道将要保存的数据量,可以查出是否有足够的可用空间,不用调用getFreeSpace()或 getTotalSpace()引起IOException。它们表示目前可用空间 和存储卷中的总空间。此信息可以用来避免填充在存储卷的容量超出特定阈值。
但是系统并不保证我们可以写入 与getFreeSpace()得的一样多的字节,如果返回的数组比我们要保存的数据大小大出几MB,或者文件系统所占空间不到90%,则可以安全继续操作,否则,可能会写入存储失败。
注意:保存文件之前,不用检查空间可用量。可以尝试立刻写入文件,然后在IOException出现时将其捕获。例如,如果在保存文件之前见PNG图片转换成JPEG更改了文件编码,这种情况下是无预知文件大小的.
4.删除文件
删除文件最直接的方法,就是让打开的文件自行调用delete():
myFile.delete();
如果文件保存在内部存储中,可以使用Context调用deleteFile()定位和删除文件:
myContext.deleteFile(fileName);
注意:当应用被卸载时,Android系统会删除一下各项:
保存在内部存储中的所有文件
使用getExternalFilesDir()保存在外部存储中的所有文件。
但是,必须手动删除使用getCacheDir()定期创建的所有缓存文件并且定期删除不再需要的其他文件
三、使用SQL数据库保存数据
将数据保存到数据库对于重复或结构化数据(比如契约信息) 而言是理想之选,这里不作具体描述,因为android sql的使用根据应用场景的多边性 没有固定模式