最近开发的 Android 应用中需要添加保存用户状态的功能, 经过查阅 Android 的文档, 保存用户状态的几种方法如下:
Android 系统提供的 Bundle 类似于哈希表, 以 key、 value 的形式保存数据, 支持存取几种常见的类型。 最先找到的文档就是通过 Activity 的 onSaveInstanceState 和 onRestoreInstanceState 方法来保存用户状态, 虽然最终测试发现这种方法不是肯靠谱, 还是记录下来了。
当系统销毁 Android 程序, 进行内存回收时, 会调用 Activity 的 onSaveInstanceState 方法, 传入一个 Bundle 实例参数, 通过重写这个方法, 可以保存 Activity 的状态, 示例代码如下:
protected override void OnSaveInstanceState(Bundle outState) {
base.OnSaveInstanceState(outState);
outState.PutInt("main_activity_click_count", _count);
outState.PutString("main_activity_button_text", _myButton.Text);
}
对于 Fragment 来说, 也是重写这个方法。
当系统重新回到以前被系统回收的应用时, 会调用 onRestoreInstanceState 方法, 如果之前用 onSaveInstanceState 保存了状态, 则可以通过重写 onRestoreInstanceState 方法恢复状态。
对于 Activity 来说, 可以在 onCreate 方法中读取保存的状态, 代码如下:
protected override void OnCreate(Bundle bundle) {
base.OnCreate(bundle);
if (bundle != null) {
/* retain ui state */
}
}
也可以在 onRestoreInstanceState 方法中读取保存的状态, 代码如下:
protected override void OnRestoreInstanceState(Bundle savedInstanceState) {
base.OnRestoreInstanceState(savedInstanceState);
_count = savedInstanceState.GetInt("main_activity_click_count", _count);
_myButton.Text = savedInstanceState.GetString("main_activity_button_text", "Nothing in state.");
}
对于 Fragment 来说, 可以在 onCreate 、 onActivityCreated 、 onCreateView 中读取 onSaveInstanceState 方法中保存的状态, 这三个方法分别如下:
public override void OnCreate(Bundle savedInstanceState) {
base.OnCreate(savedInstanceState);
}
public override void OnActivityCreated(Bundle savedInstanceState) {
base.OnActivityCreated(savedInstanceState);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return base.OnCreateView(inflater, container, savedInstanceState);
}
经过测试, 这种方法最大的缺点就是不靠谱 , 因为 onSaveInstanceState 和 onResotreInstanceState 不是每次都能被系统调用, 因为应用可能在调用 onRestoreInstanceState 方法之前应用就被结束了, 大家都喜欢装杀进程的软件, 应用程序总免不了被结束的命运, 所以这种方法不是很可靠的。
Android 推荐在 onPause 方法中使用 SharedPreference 保存状态是比较可靠的, 因为 SharedPreference 是基于文件的, 所以被结束进程也不怕。
不管是 Activity 还是 Fragment , 都可以通过重写 onPause 方法来保存状态, 代码如下:
protected override void OnPause() {
base.OnPause();
var pref = this.GetPreferences(FileCreationMode.Private);
var editor = pref.Edit();
editor.PutInt("main_activity_click_count", _count);
editor.PutString("main_activity_button_text", _myButton.Text);
editor.Commit();
}
虽然可以在任何时候读取保存的 SharedPreference , 但是还是推荐在 onCreate 方法中读取保存的内容, 示例代码如下:
protected override void OnCreate(Bundle bundle) {
base.OnCreate(bundle);
/* setup code here */
var pref = this.GetPreferences(FileCreationMode.Private);
_count = pref.GetInt("main_activity_click_count", _count);
_myButton.Text = pref.GetString("main_activity_button_text", "Nothing in state.");
}
Activity 有两个方法来创建 SharedPreference , getPreferences 和 getSharedPreferences , getPreference 创建的 SharedPreference 只能在当前的 Activity 中访问, 而 getSharedPreference 创建的选项则可以在整个应用中访问。
保存用户状态建议积极一些, 不要总是等待系统调用 onPause 方法, 只要用户操作了界面, 就可以进行状态保存, 这样会让应用更加可靠一些。