Android ApiDemos详解之App_Activity_Persistent State
从名字”Persistent State”就可以猜出该示例大概是讲解维持”可持续状态”的功能点,首先还是从直观的效果图开始吧,点击”Persistent State”后进入下图:
布局代码如下:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout android:orientation="vertical" android:padding="4dip"
android:layout_width="match_parent"android:layout_height="wrap_content">
<TextView android:id="@+id/msg"
android:layout_width="match_parent"android:layout_height="wrap_content"
android:layout_weight="0"android:textAppearance="?android:attr/textAppearanceMedium"
android:paddingBottom="4dip"/>
<TextView
android:layout_width="match_parent"android:layout_height="wrap_content"
android:layout_weight="0"android:paddingBottom="4dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/saves_state"/>
<EditText android:id="@+id/saved"
android:layout_width="match_parent"android:layout_height="wrap_content"
android:layout_weight="1"android:background="@drawable/green"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/initial_text"
android:freezesText="true">
</EditText>
<TextView
android:layout_width="match_parent"android:layout_height="wrap_content"
android:layout_weight="0"android:paddingTop="8dip" android:paddingBottom="4dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/no_saves_state"/>
<EditText
android:layout_width="match_parent"android:layout_height="wrap_content"
android:layout_weight="1"android:background="@drawable/red"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/initial_text">
</EditText>
</LinearLayout>
</ScrollView>
这里需要提醒大家的是当ScrollView用作父容器时其只能包含一个子元素,不然会报错,这里大家可以看到只包含了一个LinearLayout布局容器。代码很简单,从上至下分别是一个用以描述示例的TextView,以及两对TextView和EditText组合,一个是保存更改状态的另一个是不保存更改状态的。在布局文件中唯一需要提到的是一个用以描述字体大小的属性:
android:textAppearance="?android:attr/textAppearanceMedium"
该种属性一共有三种,另外两种是:
android:textAppearance="?android:attr/textAppearanceLarge"
android:textAppearance="?android:attr/textAppearanceSmall"
接下来我们分别在背景分别是绿色和红色的两个EditText中输入一句话:
接下来我们要做的是点击设备上的返回键,然后再次点击”Persistent State”进入该示例:
可见绿色背景的”QQ”还保存着,而红色背景的”QICQ”已经不见了,恢复到了原先的”Initialtext.”,这样的保存效果可能让大家想起了登录XXX客户端时保存账户和密码的功能,在看代码之前先附上一个非常重要的图,即Activity的生命周期图(官方的):
接下来先附上该示例的主要代码:
protected void onResume() {
super.onResume();
SharedPreferences prefs =getPreferences(0);
String restoredText = prefs.getString("text", null);
if (restoredText != null) {
mSaved.setText(restoredText, TextView.BufferType.EDITABLE);
int selectionStart = prefs.getInt("selection-start", -1);
int selectionEnd = prefs.getInt("selection-end", -1);
if (selectionStart != -1 &&selectionEnd != -1) {
mSaved.setSelection(selectionStart, selectionEnd);
}
}
}
protected void onPause() {
super.onPause();
SharedPreferences.Editor editor =getPreferences(0).edit();
editor.putString("text", mSaved.getText().toString());
editor.putInt("selection-start", mSaved.getSelectionStart());
editor.putInt("selection-end", mSaved.getSelectionEnd());
editor.commit();
}
本实例重写了Activity的两个生命周期的方法onResume()和onPause(),其中onResume()是在onStart()之后执行的一个方法,也就是Activity在运行之前必执行的方法。而onPause()却很特殊,因为该方法是当前Activity在意外被销毁或者变为invisible之前的最后一个安全的必执行方法,所以在设计App时很多重要的保存执行步骤都需要在onPause()写入。
先来看重写的onPause()方法,其中有一个很重要的类是SharedPreference,它是Android平台上一个轻量级的存储类,主要是用于小数据的存储和用于恢复状态,最终数据是以XML文件的形式进行保存,保存在保存在 /data/data/PACKAGE_NAME /shared_prefs 目录下。而SharedPreference.Editor是一个接口,用于更改SharedPreference内的值,而在调用commit()或者apply()之前所有更改都不会生效。在方法getPreferences(0)中的”0”实际上是参数
public static final int MODE_PRIVATE = 0x0000
它为默认模式,作用是声明创建的文件只能被调用它的应用进入,或者是分享同一Uers ID的其他应用进入。
Editor分别保存了三个键值对,
1.”text”---mSaved.getText().toString()
2."selection-start"---mSaved.getSelectionStart()
3."selection-end"---mSaved.getSelectionEnd()
其中:
1.”text”对应的值是绿色背景的EditText在Activity执行onPause()前所包含的内容;
2.“selection-start”对应的值是当前EditText被选择中的文本的起始位置;
3.”selection-end”对应的值是当前EditText被选择中的文本的终止位置。
比如下图:
“text”对应的值是QQ333;”selection-start”对应的值是2;”selection-end”对应的值5(位置是从1开始而不是0,需要注意);
最后来看一下如果当前的Activity被其他Activity压在栈下后再恢复的时候,调用onResume()时的处理方法:
protected void onResume() {
super.onResume();
SharedPreferences prefs =getPreferences(0);
String restoredText = prefs.getString("text",null);
if (restoredText != null) {
mSaved.setText(restoredText, TextView.BufferType.EDITABLE);
int selectionStart = prefs.getInt("selection-start", -1);
int selectionEnd = prefs.getInt("selection-end", -1);
if (selectionStart != -1 &&selectionEnd != -1) {
mSaved.setSelection(selectionStart, selectionEnd);
}
}
}
该方法就很明白了,第一步将保存在SharedPreferences中的内容根据键值对一一取出,然后判断是否文本内容为空,否的话将其显示在绿色背景的EditText上,然后在取出选择区域的文本起始和终止位置的值,如果都不为-1的话则将EditText文本内容做选定操作。
本期到此结束。