7.3. SharedPreferences
7.3.SharedPreferences
已经有了选项界面,也有了存储用户名、密码、API root等选项数据的办法,剩下的就是读取选项数据了。要在程序中访问选项数据的内容,就使用Android框架的SharedPreference类。
这个类允许我们在程序的任何部分(比如Activity,Service,BroadcastReceiver,ContentProvider)中访问选项数据,这也正是SharedPreference这个名字的由来。
在StatusActivity中新加入一个成员prefs:
SharedPreferences prefs;
然后在onCreate()中添加一段代码,获取SharedPreferences对象的引用。
@Override
public void onCreate(Bundle savedInstanceState) {
...
// Setup preferences
prefs = PreferenceManager.getDefaultSharedPreferences(this); //
prefs.registerOnSharedPreferenceChangeListener(this); //
}
- 每个程序都有自己唯一的SharedPreferences对象,可供当前上下文中所有的构件访问。我们可以通过PreferenceManager.getDefaultSharedPreferences()来获取它的引用。名字中的"Shared"可能会让人疑惑,它是指允许在当前程序的各部分间共享,而不能与其它程序共享。
- 选项数据可以随时为用户修改,因此我们需要提供一个机制来跟踪选项数据的变化。为此我们在StatusActivity中提供一个OnSharedPreferenceChangeListener接口的实现,并注册到SharedPreferences对象中。具体内容将在后面讨论。
现在用户名、密码与API root几项都已定义。接下来我们可以重构代码中的Twitter对象部分,消除原先的硬编码。我们可以为StatusActivity添加一个私有方法,用以返回可用的twitter对象。它将惰性地初始化twitter对象,也就是先判断twitter对象是否存在,若不存在,则创建新对象。
private Twitter getTwitter() {
if (twitter == null) { //
String username, password, apiRoot;
username = prefs.getString("username", ""); //
password = prefs.getString("password", "");
apiRoot = prefs.getString("apiRoot", "http://yamba.marakana.com/api");
// Connect to twitter.com
twitter = new Twitter(username, password); //
twitter.setAPIRootUrl(apiRoot); //
}
return twitter;
}
- 仅在twitter为null时创建新对象。
- 从SharedPreferences对象中获取username与password。getString()的第一个参数是选项条目的键,比如"username"和"password",第二个参数是条目不存在时备用的默认值。因此,如果用户在登录前还没有设置个人选项,到这里用户名密码就都是空的,自然也就无法登录。但是由于jtwitter设计的原因,用户只有在尝试发送消息时才会看到错误。
- 按照用户提供的用户名密码登录。
- 我们需要提供自己的API root才可以访问twitter服务。
到这里,我们不再直接引用twitter对象,而统一改为通过getTwitter()获取它的引用。修改后的onClick()方法如下:
public void onClick(View v) {
// Update twitter status
try {
getTwitter().setStatus(editText.getText().toString());
} catch (TwitterException e) {
Log.d(TAG, "Twitter setStatus failed: " + e);
}
}
留意,我们虽将初始化的代码移到了外面,但它依然是阻塞的,可能会因为网络状况的不同产生一定的延迟。日后我们仍需对此做些考虑,利用AsyncTask来改进它。
前面修改onCreate()时曾提到,我们需要跟踪用户名与密码的变化。因此,在当前的类中添加onSharedPreferenceChanged()方法,然后在onCreate()中通过pres.registerOnSharedPreferenceChangeListener(this)将它注册到prefs对象,这样就得到一个回调函数,它会在选项数据变化时触发。在这里我们只需简单将twitter设为null,到下次获取引用时,getTwitter()会重新创建它的实例。
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// invalidate twitter object
twitter = null;
}