9.2 使用设置文件
用户在使用应用时,常常会有一些个人偏好。比如,在阅读过程中,一些用户喜欢小字体,便于快速浏览内容;而另一些用户更青睐使用大字体,使得阅读更为省力。
为了满足不同用户的需求,应用通常会提供对应的设置项(Preference),让用户根据自己的喜好选择。这些设置信息会存储在本地并进行结构化地展示,使用户可以编辑。
Android中提供了一整套的设置数据存储、浏览、编辑的解决框架,使得开发者可以轻松地为应用提供设置项。
9.2.1 设置文件的存储和使用
Android应用的设置数据,可以通过android.content.SharedPreferences类来表示。SharedPreferences提供了一组数据读取的接口,可以从设置文件中读取给定键值的整型数、布尔型数等基础类型的数据。
修改设置文件中的数据,需要使用SharedPreferences.Editor类来进行操作。所有的修改会暂存在内存之中,在用户完成修改后,开发者需要调用ShraedPreferences.Editor.commit函数,将在内存中修改过的数据批量写入到存储设备中。
一个设置文件的读写示例如下:
//在界面组件或服务组件中调用,构造应用默认的设置文件
SharedPreferences preferences=
PreferenceManager.getDefaultSharedPreferences(this);
//读取数据,如果无法找到,则会使用默认值
int aInt=preference.getInt("a_int",0);
int aBool=preference.getBoolean("a_bool",false);
//修改并写入设置数据,如果没有找到给定的键值,则会增加
SharedPreferences.Editor editor=preferences.edit();
editor
.putInt("a_int",aInt+1)
.putBoolean("a_bool",!aBool)
.commit();
其中,android.preference.PreferenceManager对象是用来辅助读取设置文件数据的。每个Android应用都可以有多个设置文件,调用Context.getSharedPreferences函数可以构造指定名字和权限的设置文件:
//构造另一设置文件
SharedPreferences preferences=getSharedPreferences(
"anther_perf",MODE_PRIVATE);
设置文件存储在应用私有目录下的shared_prefs文件夹中,默认的设置文件名为:
应用包名_preferences.xml
而通过Context.getSharedPreferences函数构造的设置文件,其文件名为:
给定名字.xml
在实践中,如果应用包含大量不同类型的设置数据,那么开发者需要将这些设置项按照使用场景进行拆分,分别存储到多个设置文件中,降低单一设置文件的大小,从而有效地提升设置文件的读写速度。
设置文件是以XML的格式进行存储,每个设置项会按照键值对的格式来描述。比如,之前示例中的设置数据,在文件中的存储形式如下:
<?xml version='1.0'encoding='utf-8'standalone='yes'?>
<map>
<int name="a_int"value="1"/>
<boolean name="a_bool"value="true"/>
</map>
不难看出,设置项中不能存储二进制数据,否则,在序列化成为xml文件后,系统将无法正确读取,从而导致设置数据丢失,致使应用逻辑出错。
为了提升设置文件的读写效率,SharedPreferences在读写方面做了很多优化。所有磁盘操作,包括设置文件的加载和写入,都会在独立的线程上进行,避免阻塞主线程。而所有设置文件的读写操作,都是线程安全的,开发时可以放心的在不同线程上对设置文件进行读取或者写入[1]。
[1]但设置文件的读写,并不是进程安全的。也就是说如果应用是多进程的,不要在不同进程中同时操作一份设置文件,这可能导致数据发生错乱。