android通常有五种数据的保存方式,三种如下,其他俩种分别是网络存储和 Content Provider
1.保存到Preferences
使用SharedPreferences文件以Key-Value的方式保存简要的信息
2.保存到文件
保存基本的文件
3.保存到数据库
使用Sqlite数据库读写数据
Preferences的使用
首先你需要先获取一个Context对象,理解Context()在继承关系上的结构。Application和Activity都是继续Context的。
写操作
Context aContext =getApplication();
SharedPreferences sharedPreferences = aContext.getSharedPreferences("name", MODE_PRIVATE);
Editor editor = sharedPreferences.edit();
editor.putBoolean(key, value);
editor.putFloat(key, value);
editor.putInt(key, value)
editor.putLong(key, value)
editor.putString(key, value)
editor.putStringSet(key, values);
editor.commit();
在这操作中,需要注意的是getSharedPreferences(String name, int mode);
name是文件的名字,若存在则打开,不存在则新建一个。mode是存在Context中的静态int 数据标志flag,有MODE_PRIVATE,MODE_WORLD_READABLE,MODE_WORLD_WRITEABLE,MODE_MULTI_PROCESS 但MODE_WORLD_READABLE,MODE_WORLD_WRITEABLE不推荐被使用。通常使用需要用 Context.MODE_PRIVATE
读操作
Context aContext =getApplication();
SharedPreferences sharedPreferences = aContext.getSharedPreferences("name", MODE_PRIVATE);
String kk = sharedPreferences.getString(key, defValue);
这个需要注意的是defvalue的值,这个读取数据当这个key没有数据的时候的返回值。
保存到文件File
File(File dir, String name)
Constructs a new file using the specified directory and name.
File(String path)
Constructs a new file using the specified path.
File(String dirPath, String name)
Constructs a new File using the specified directory path and file name, placing a path separator between the two.
File(URI uri)
Constructs a new File using the path of the specified URI.
这个时候需要科普的是指是,android 设备有俩个文件存储区域,”internal”和”external”储存,sd card (external storage)为可卸载的存储部件。虽然后来有点变化,但从一块手机内置的储存中,在逻辑上是分为internl和external
俩者有什么区别呢?
Internal storage:
- 总是可用的
- 这里的文件默认是只能被你的app所访问的。
- 当用户卸载你的app的时候,系统会把internal里面的相关文件都清楚干净。
- Internal是你在想确保不被用户与其他app所访问的最佳储存场所。
External storage:
- 并不总是可用的,因为用户可以选择把这部分作为USB储存模式,这样就不可以访问了。
- 是大家都可以访问的,因此保存到这里的文件是失去访问控制权限的。
- 当用户卸载你的app时,系统仅仅会删除external根目录 getApplication().getExternalFilesDir(type); 下的相关文件。
- External是在你不需要严格的访问权限兵长你希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。
尽管app的默认被安装到 internal storage的。你还可以通过mainifest文件声明android:installLocation属性来指定程序安装到external storage。当程序很大的时候,很多人倾向安装到external storage。
获取External储存的储存权限
为了写数据到external storage,我们需要在mainfest 文中中申请WRITE_EXTERNAL_STORAGE权限。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- 上面的是读权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 上面的是写权限-->
有写权限就默认有读的权限
对于internal storage,不需要声明任何的权限,因为我们的程序默认就有读写程序目录下的文件的权限。
保存到Internal Storage
当保存在文件到internal storage 的时候,我们可以通过俩个方法来获取合适的目录。
- context.getFilesDir() :返回一个file,表示你的app的internal目录
- context.getCacheDir() :返回一个file,表示你的app的internal缓存目录,既然是缓存目录,那么就是这个文件一旦不需要的时候能够马上被删除,而且给予明确的缓存大小。在系统的内部储存空间不够的时候,会自动选择删除缓存文件。
在那些目录下可以创建新的文件,如下File file = new File(getFilesDir(), "filename");
有多种的方式可以写入internal目录,例如执行openFileOutput来获取一个FileOutputStream来写入目录。这个方面需要了解一下linux的I/O 函数的使用,毕竟android的内核是linux
String filename = "newfile";
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
在上面的方法中,需要注意的是 留意 ContextWrapper类,这个是对Context的代理实现一些方法。里面有对文件路径的获取方法。
写入目录。这个方面需要了解一下linux的I/O 函数的使用,毕竟android的内核是linux
创建缓存文件的另一个方法就是 File.createTempFile();
public File getTempFile(Context context, String url) {
File file = null;
try {
String fileName = Uri.parse(url).getLastPathSegment();
file = File.createTempFile(fileName, null, context.getCacheDir());
//从某种角度,函数有多种,基本都有自己的职能。在某一领域适用
}
catch (IOException e) {
// Error while creating file
}
return file;
}
//File createTempFile(String prefix, String suffix)
//File createTempFile(String prefix, String suffix, File directory)
//createTempFile有俩种方法,第一种路径File默认为null
app在internal storage目录是以app的包名为标识存放在android文件系统的特定目录下的[data/data/com.example.xx]。从技术上讲,如果你的文件设置为可读的,那么其他app就可以读取你的internal文件。然而,其他app需要知道你的包名与文件名。若是你没有设置为刻毒或者可写,其他app事没有办法读写的,因此使用MODE_PRIVATE,那么这些文件就不可能被其他app所访问。
保存文件到 External Storage
首先,我们可以确定的是 external storage 可能是不可用的,比如SD卡被拔出,那么在访问之前需要判断是否可用。可以用 getExternalStorageState()来查询external storage的状态。如果返回的 MEDIA_MOUNTED ,那么该External Storage就可读写。详情注意 一下 Environment 类
/*下面的函数判断external storage 是否可读可写 */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/* 检查external storage 至少可以读*/
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
尽管external storage对于用户与app是可修改的,但我们可能会保存为下面俩种类型的文件。
- Public files:这些文件对于用户和其他app是public的,当用户卸载你的app的时候,这些文件应该保留。例如,那些被你的app拍摄的照片或者下载的文件。
- Private files:这些文件被你的app所拥有,在你的app被卸载的时候,应该被卸载掉。尽管可以被其他的app所访问,但实际上对其他的app是没有意义的。所以,当用户卸载你的app的时候,系统会删除 你的app的private目录。例如,那些被你的app下载的缓存文件。
如果想保存文件为public形式 Environment.getExternalStoragePublicDirectory()
保存文件为private 的方式 Environment.getExternalFilesDir()
有一点也比较重要的是设置参数。Environment.DIRECTORY_PICTURES ,表示文件存储的类型被标识为 pictures
Environment 注意的是 DIRECTORY_和 MEDIA_ 前缀
查询剩余空间
在保存文件之前,首先我更需要确认的是有没有剩下的空间
File 的getFreeSpace() 函数,返回的是long,单位bytes
File:public long getTotalSpace() public long getUsableSpace()
Returns 0 if this path does not exist 返回0代表路径不存在
删除文件
当不需要某些文件的时候,删除它。最直接的方法是
myFile.delete();//直接删除
myContext.deleteFile(fileName);//如果文件是保存在internal storage
注意的是,当用户卸载你的app时,android系统会删除下面的文件:
- 所有保存到internal storage的文件。
- 所有使用getExternalFilesDir()保存在external storage的文件。
但是,通常而言,我们应该手动删除所有通过getCacheDir()方式创建的缓存文件还有那些不会在用到的文件。
###Sqlite数据库