备忘录模式实现与研究 - bei1999/work GitHub Wiki
保存对象状态,之后可以再次恢复到此状态,类似于日常说的“后悔药”,为了保护状态完整性以及内部实现不向外暴露,也就是说不能被对象从外部访问。
在不破坏封闭的前提下,将该对象之外保存这个状态,需要的时候可以将保存的对象恢复到原来的保存状态
- android 中Activity 中的状态保存
public class MainActivity09 extends BaseActivity {
@Override
public int getLayoutId() {
return R.layout.activity_main;
}
@Override
public void initPresenter() {
//TODO
}
@Override
public void initView() {
//TODO
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
}
// AppCompatActivity 中的一段代码
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getDelegate().onSaveInstanceState(outState);
}
/**
* Save all appropriate fragment state.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
if (mPendingFragmentActivityResults.size() > 0) {
outState.putInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG, mNextCandidateRequestIndex);
int[] requestCodes = new int[mPendingFragmentActivityResults.size()];
String[] fragmentWhos = new String[mPendingFragmentActivityResults.size()];
for (int i = 0; i < mPendingFragmentActivityResults.size(); i++) {
requestCodes[i] = mPendingFragmentActivityResults.keyAt(i);
fragmentWhos[i] = mPendingFragmentActivityResults.valueAt(i);
}
outState.putIntArray(ALLOCATED_REQUEST_INDICIES_TAG, requestCodes);
outState.putStringArray(REQUEST_FRAGMENT_WHO_TAG, fragmentWhos);
}
}
//跳转到Activity 中的super调用
protected void onSaveInstanceState(Bundle outState) {
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
getApplication().dispatchActivitySaveInstanceState(this, outState);
}
/**
* This method is called after {@link #onStart} when the activity is
* being re-initialized from a previously saved state, given here in
* <var>savedInstanceState</var>. Most implementations will simply use {@link #onCreate}
* to restore their state, but it is sometimes convenient to do it here
* after all of the initialization has been done or to allow subclasses to
* decide whether to use your default implementation. The default
* implementation of this method performs a restore of any view state that
* had previously been frozen by {@link #onSaveInstanceState}.
*
* <p>This method is called between {@link #onStart} and
* {@link #onPostCreate}.
*
* @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}.
*
* @see #onCreate
* @see #onPostCreate
* @see #onResume
* @see #onSaveInstanceState
*/
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (mWindow != null) {
Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG);
if (windowState != null) {
mWindow.restoreHierarchyState(windowState);
}
}
}
onSaveInstanceState方法中,分为三个步骤
- 存储窗口的视图数的状态
- 存储了fragment 的状态
- 通过Activity 的ActivityLifeCallbacks dispatchActivitySaveInstanceState 方式进行了存储状态
onRestoreInstanceState方法则通过把存储的Bundle 交给系统的window 进行了恢复restoreHierarchyState
onSaveInstanceState 调用的时机 并不是每次activity 退出之前都会调用,当某个activity变得容易被系统销毁时,该activity 的onSaveInstanceState就会执行,常见如下:
- 用户按home键
- 长按home键,切换其他app
- 按电源(关闭屏幕)
- 屏幕方向切换
- 呼入电话时候 概括是,不是用户主动退出或者跳转七天activity就会触发,即当系统存在“未经你许可”时销毁了我们的activity,则onSaveInstanceState会执行,系统这样做的目的是提供保存用户数据的时机。
备忘录模式是在不破坏封装条件下的对内部状态的存储和还原 优点:提供了一种可恢复的时机 缺点:如果需要的数据大,保存和恢复有一定的内存消耗