7.3. SharedPreferences

优质
小牛编辑
129浏览
2023-12-01

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); //

}

  1. 每个程序都有自己唯一的SharedPreferences对象,可供当前上下文中所有的构件访问。我们可以通过PreferenceManager.getDefaultSharedPreferences()来获取它的引用。名字中的"Shared"可能会让人疑惑,它是指允许在当前程序的各部分间共享,而不能与其它程序共享。
  2. 选项数据可以随时为用户修改,因此我们需要提供一个机制来跟踪选项数据的变化。为此我们在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;

}

  1. 仅在twitter为null时创建新对象。
  2. 从SharedPreferences对象中获取username与password。getString()的第一个参数是选项条目的键,比如"username"和"password",第二个参数是条目不存在时备用的默认值。因此,如果用户在登录前还没有设置个人选项,到这里用户名密码就都是空的,自然也就无法登录。但是由于jtwitter设计的原因,用户只有在尝试发送消息时才会看到错误。
  3. 按照用户提供的用户名密码登录。
  4. 我们需要提供自己的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;

}