保存到Preference
SharedPreference是Android提供的一种轻量级的数据存储方式,主要用来存储一些简单的配置信息,例如,默认欢迎语,登录用户名和密码等。其以键值对的方式存储,使得我们能很方便进行读取和存入。
当有一个相对较小的key-value集合需要保存时,可以使用SharedPreferences APIs。 SharedPreferences 对象指向一个保存key-value pairs的文件,并为读写他们提供了简单的方法。每个 SharedPreferences 文件均由framework管理,其既可以是私有的,也可以是共享的。
获取SharedPreference
我们可以通过以下两种方法之一创建或者访问shared preference 文件:
(1)getPreferences() — 当activity仅需要一个shared preference文件时。因为该方法会检索activity下默认的shared preference文件,并不需要提供文件名称。
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
- (2)getSharedPreferences() — 如果需要多个通过名称参数来区分的shared preference文件, 名称可以通过第一个参数来指定。可在app中通过任何一个Context 执行该方法。
Context context = getActivity();
SharedPreferences sharedPref = context.getSharedPreferences(
getString(R.string.preference_file_key), Context.MODE_PRIVATE);
注:如果创建了一个MODE_WORLD_READABLE或者MODE_WORLD_WRITEABLE 模式的shared preference文件,则其他任何app均可通过文件名访问该文件。设置为MODE_PRIVATE,该文件仅能被我们的app访问。
写Shared Preference
- 为了写shared preferences文件,需要通过执行edit()创建一个 SharedPreferences.Editor。
- 通过类似putInt()与putString()等方法传递keys与values,接着通过commit() 提交改变.
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.saved_high_score), newHighScore);
editor.commit();
读Shared Preference
- 为了从shared preference中读取数据,可以通过类似于 getInt() 及 getString()等方法来读取。在那些方法里面传递我们想要获取的value对应的key,并提供一个默认的value作为查找的key不存在时函数的返回值。如下:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
long highScore = sharedPref.getInt(getString(R.string.saved_high_score), default);
保存到文件
- File 对象非常适合于流式顺序数据的读写。如图片文件或是网络中交换的数据等。
存储在内部还是外部
所有的Android设备均有两个文件存储区域:”internal” 与 “external” 。 这两个名称来自于早先的Android系统,当时大多设备都内置了不可变的内存(internal storage)及一个类似于SD card(external storage)这样的可卸载的存储部件。之后有一些设备将”internal” 与 “external” 都做成了不可卸载的内置存储,虽然如此,但是这一整块还是从逻辑上有被划分为”internal”与”external”的。只是现在不再以是否可卸载进行区分了。 下面列出了两者的区别:
Internal storage:
总是可用的。
这里的文件默认只能被我们的app所访问。
当用户卸载app的时候,系统会把internal内该app相关的文件都清除干净。
Internal是我们在想确保不被用户与其他app所访问的最佳存储区域。- External storage:
并不总是可用的,因为用户有时会通过USB存储模式挂载外部存储器,当取下挂载的这部分后,就无法对其进行访问了。
是大家都可以访问的,因此保存在这里的文件可能被其他程序访问。
当用户卸载我们的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。
External是在不需要严格的访问权限并且希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。
注尽管app是默认被安装到internal storage的,我们还是可以通过在程序的manifest文件中声明android:installLocation 属性来指定程序安装到external storage。
保存到Internal Storage
getFilesDir() : 返回一个File,代表了我们app的internal目录。
getCacheDir() : 返回一个File,代表了我们app的internal缓存目录。请确保这个目录下的文件能够在一旦不再需要的时候马上被删除,并对其大小进行合理限制,例如1MB 。系统的内部存储空间不够时,会自行选择删除缓存文件。
存、取、删除
public static void saveLoginData(Context context, LoginData data) {
File file = new File(context.getFilesDir(), LOGIN_URI_DATAS);
if (file.exists()) {
file.delete();
}
try {
ObjectOutputStream oos = new ObjectOutputStream(
context.openFileOutput(LOGIN_URI_DATAS, Context.MODE_PRIVATE));
oos.writeObject(data);
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static LoginData loadLoginData(Context context) {
LoginData data = null;
File file = new File(context.getFilesDir(), LOGIN_URI_DATAS);
if (file.exists()) {
try {
ObjectInputStream ois = new ObjectInputStream(
context.openFileInput(LOGIN_URI_DATAS));
data = (LoginData) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return data;
}
public static void deleteLoginData(Context context){
File file = new File(context.getFilesDir(), LOGIN_URI_DATAS);
if (file.exists()){
file.delete();
}
}
- 如果需要缓存一些文件,可以使用createTempFile()。例如:下面的方法从URL中抽取了一个文件名,然后再在程序的internal缓存目录下创建了一个以这个文件名命名的文件。
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;
}
保存文件到External Storage
- 因为external storage可能是不可用的,比如遇到SD卡被拔出等情况时。因此在访问之前应对其可用性进行检查。我们可以通过执行 getExternalStorageState()来查询external storage的状态。若返回状态为MEDIA_MOUNTED, 则可以读写。示例如下:
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
- 注:当用户卸载我们的app时,android系统会删除以下文件:
所有保存到internal storage的文件。
所有使用getExternalFilesDir()方式保存在external storage的文件。
然而,通常来说,我们应该手动删除所有通过 getCacheDir() 方式创建的缓存文件,以及那些不会再用到的文件。