Android BaseSavedState 以及 Activity onSaveInstanceState 和 onRestoreInstanceState 方法使用注意事项
2014-03-07 17:03
706 查看
下面的代码来自View这个类,是一个关于状态保存的类,我们浏览器用与崩溃恢复,很有用的哦,我还看到过同事用来做View的状态保存,反正很强大的说~
/**
* Base class for derived classes that want to save and restore their own
* state in {@link android.view.View#onSaveInstanceState()}.
*/
public static class BaseSavedState extends AbsSavedState {
/**
* Constructor used when reading from a parcel. Reads the state of the superclass.
*
* @param source
*/
public BaseSavedState(Parcel source) {
super(source);
}
/**
* Constructor called by derived classes when creating their SavedState objects
*
* @param superState The state of the superclass of this view
*/
public BaseSavedState(Parcelable superState) {
super(superState);
}
public static final Parcelable.Creator<BaseSavedState> CREATOR =
new Parcelable.Creator<BaseSavedState>() {
public BaseSavedState createFromParcel(Parcel in) {
return new BaseSavedState(in);
}
public BaseSavedState[] newArray(int size) {
return new BaseSavedState[size];
}
};
}
相关的有Activity的onSaveInstanceState,onRestoreInstanceState:
这些都和状态保存相关系的~值得深入理解一下
比如在HorizontalScrollView 中的最后一段代码,就用来保存View的状态:
http://blog.csdn.net/murongshusheng/article/details/8199538
这里总结了很多细节,我之前就疏忽了为什么按back键就不保存状态呢?原来不是什么时候都保存状态的。
1.在一个activity被销毁前,不一定会调用
2.如果这个方法被调用,它一定会在
3.布局中的每一个View默认实现了
4.由于默认的
5.由于
文章链接:http://blog.csdn.net/murongshusheng/article/details/8199538
实例,写的很棒:是一个自定义View SaveState的例子,非常好。
http://disanji.net/2011/04/28/android-view-onsaveinstancestate-onrestoreinstancestate/
后面主要写写Activity onSaveInstanceState 和 onRestoreInstanceState 方法使用注意事项,我觉得这个地方非常重要:
在Activity中,有两个方法用于临时保存、恢复状态信息,注意是临时信息,如果你关机重启肯定保存不了。这两个方法是:
public void onSaveInstanceState(Bundle savedInstanceState);
public void onRestoreInstanceState(Bundle savedInstanceState);
在写Demo测试Activity生命周期的时候,发现onRestoreInstanceState方法并不会总是被调用,上网查了一下,这两个方法主要用于在切换屏幕布局时保存APP数据的,文章中提到“如果我们的Activity在后台没有因为运行内存吃紧被清理,则切换回时会触发onRestoreInstanceState方法”。因为内存回收不受我们控制,所以在除了在切换屏幕保存数据状态以外,最好使用onPause方法和onResume方法来保存和读取程序状态。
以下几种情况会调用onSaveInstanceState,分别是:
用户按下HOME键;
长按HOME键,选择运行其他的程序;
按下电源按键;
屏幕方向切换(可能);
启动新的Activity等;
适合临时信息:当要保存持久信息时,不要使用这个保存方法!举个简单的例子,当我们点击Home后,onSaveInstanceState方法会被调用,此时,如果从Settings里面终止程序,那么,回来后发现保存的数据是不存在的。
至于这两个函数的使用,给出示范代码(留意自定义代码在调用super的前或后):
参考:(下面的链接都非常有价值)
http://blog.csdn.net/ddna/article/details/5123482 http://blog.csdn.net/spare_h/article/details/6659010 http://android.blog.51cto.com/268543/634646/ http://www.th7.cn/Program/Android/201312/162981.shtml http://www.charlesharley.com/2012/programming/views-saving-instance-state-in-android/ http://stackoverflow.com/questions/3542333/how-to-prevent-custom-views-from-losing-state-across-screen-orientation-changes http://stackoverflow.com/questions/14891434/overriding-view-onsaveinstancestate-and-view-onrestoreinstancestate-using-vi https://github.com/CharlesHarley/Example-Android-SavingInstanceState/blob/master/src/com/example/android/savinginstancestate/views/LockCombinationPicker.java
/**
* Base class for derived classes that want to save and restore their own
* state in {@link android.view.View#onSaveInstanceState()}.
*/
public static class BaseSavedState extends AbsSavedState {
/**
* Constructor used when reading from a parcel. Reads the state of the superclass.
*
* @param source
*/
public BaseSavedState(Parcel source) {
super(source);
}
/**
* Constructor called by derived classes when creating their SavedState objects
*
* @param superState The state of the superclass of this view
*/
public BaseSavedState(Parcelable superState) {
super(superState);
}
public static final Parcelable.Creator<BaseSavedState> CREATOR =
new Parcelable.Creator<BaseSavedState>() {
public BaseSavedState createFromParcel(Parcel in) {
return new BaseSavedState(in);
}
public BaseSavedState[] newArray(int size) {
return new BaseSavedState[size];
}
};
}
相关的有Activity的onSaveInstanceState,onRestoreInstanceState:
/** * Called to retrieve per-instance state from an activity before being killed * so that the state can be restored in {@link #onCreate} or * {@link #onRestoreInstanceState} (the {@link Bundle} populated by this method * will be passed to both). * * <p>This method is called before an activity may be killed so that when it * comes back some time in the future it can restore its state. For example, * if activity B is launched in front of activity A, and at some point activity * A is killed to reclaim resources, activity A will have a chance to save the * current state of its user interface via this method so that when the user * returns to activity A, the state of the user interface can be restored * via {@link #onCreate} or {@link #onRestoreInstanceState}. * * <p>Do not confuse this method with activity lifecycle callbacks such as * {@link #onPause}, which is always called when an activity is being placed * in the background or on its way to destruction, or {@link #onStop} which * is called before destruction. One example of when {@link #onPause} and * {@link #onStop} is called and not this method is when a user navigates back * from activity B to activity A: there is no need to call {@link #onSaveInstanceState} * on B because that particular instance will never be restored, so the * system avoids calling it. An example when {@link #onPause} is called and * not {@link #onSaveInstanceState} is when activity B is launched in front of activity A: * the system may avoid calling {@link #onSaveInstanceState} on activity A if it isn't * killed during the lifetime of B since the state of the user interface of * A will stay intact. * * <p>The default implementation takes care of most of the UI per-instance * state for you by calling {@link android.view.View#onSaveInstanceState()} on each * view in the hierarchy that has an id, and by saving the id of the currently * focused view (all of which is restored by the default implementation of * {@link #onRestoreInstanceState}). If you override this method to save additional * information not captured by each individual view, you will likely want to * call through to the default implementation, otherwise be prepared to save * all of the state of each view yourself. * * <p>If called, this method will occur before {@link #onStop}. There are * no guarantees about whether it will occur before or after {@link #onPause}. * * @param outState Bundle in which to place your saved state. * * @see #onCreate * @see #onRestoreInstanceState * @see #onPause */ 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); } } }
这些都和状态保存相关系的~值得深入理解一下
比如在HorizontalScrollView 中的最后一段代码,就用来保存View的状态:
static class SavedState extends BaseSavedState { public int scrollPosition; public boolean isLayoutRtl; SavedState(Parcelable superState) { super(superState); } public SavedState(Parcel source) { super(source); scrollPosition = source.readInt(); isLayoutRtl = (source.readInt() == 0) ? true : false; } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeInt(scrollPosition); dest.writeInt(isLayoutRtl ? 1 : 0); } @Override public String toString() { return "HorizontalScrollView.SavedState{" + Integer.toHexString(System.identityHashCode(this)) + " scrollPosition=" + scrollPosition + " isLayoutRtl=" + isLayoutRtl + "}"; } public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() { public SavedState createFromParcel(Parcel in) { return new SavedState(in); } public SavedState[] newArray(int size) { return new SavedState[size]; } }; }
http://blog.csdn.net/murongshusheng/article/details/8199538
这里总结了很多细节,我之前就疏忽了为什么按back键就不保存状态呢?原来不是什么时候都保存状态的。
1.在一个activity被销毁前,不一定会调用
onSaveInstanceState()这个方法,因为不是所有情况都需要去存储activity的状态(例如当用户按回退键退出你的activity的时候,因为用户指定关掉这个activity)。
2.如果这个方法被调用,它一定会在
onStop()方法之前,可能会在onPause()方法之前。
3.布局中的每一个View默认实现了
onSaveInstanceState()方法,这样的话,这个UI的任何改变都会自动的存储和在activity重新创建的时候自动的恢复。但是这种情况只有在你为这个UI提供了唯一的ID之后才起作用,如果没有提供ID,将不会存储它的状态。
4.由于默认的
onSaveInstanceState()方法的实现帮助UI存储它的状态,所以如果你需要覆盖这个方法去存储额外的状态信息时,你应该在执行任何代码之前都调用父类的
onSaveInstanceState()方法(
super.onSaveInstanceState())。
5.由于
onSaveInstanceState()方法调用的不确定性,你应该只使用这个方法去记录activity的瞬间状态(UI的状态)。不应该用这个方法去存储持久化数据。当用户离开这个activity的时候应该在
onPause()方法中存储持久化数据(例如应该被存储到数据库中的数据)。
文章链接:http://blog.csdn.net/murongshusheng/article/details/8199538
实例,写的很棒:是一个自定义View SaveState的例子,非常好。
http://disanji.net/2011/04/28/android-view-onsaveinstancestate-onrestoreinstancestate/
后面主要写写Activity onSaveInstanceState 和 onRestoreInstanceState 方法使用注意事项,我觉得这个地方非常重要:
在Activity中,有两个方法用于临时保存、恢复状态信息,注意是临时信息,如果你关机重启肯定保存不了。这两个方法是:
public void onSaveInstanceState(Bundle savedInstanceState);
public void onRestoreInstanceState(Bundle savedInstanceState);
在写Demo测试Activity生命周期的时候,发现onRestoreInstanceState方法并不会总是被调用,上网查了一下,这两个方法主要用于在切换屏幕布局时保存APP数据的,文章中提到“如果我们的Activity在后台没有因为运行内存吃紧被清理,则切换回时会触发onRestoreInstanceState方法”。因为内存回收不受我们控制,所以在除了在切换屏幕保存数据状态以外,最好使用onPause方法和onResume方法来保存和读取程序状态。
以下几种情况会调用onSaveInstanceState,分别是:
用户按下HOME键;
长按HOME键,选择运行其他的程序;
按下电源按键;
屏幕方向切换(可能);
启动新的Activity等;
适合临时信息:当要保存持久信息时,不要使用这个保存方法!举个简单的例子,当我们点击Home后,onSaveInstanceState方法会被调用,此时,如果从Settings里面终止程序,那么,回来后发现保存的数据是不存在的。
至于这两个函数的使用,给出示范代码(留意自定义代码在调用super的前或后):
@Override public void onSaveInstanceState(Bundle savedInstanceState) { savedInstanceState.putBoolean("MyBoolean", true); savedInstanceState.putDouble("myDouble", 1.9); savedInstanceState.putInt("MyInt", 1); savedInstanceState.putString("MyString", "Welcome back to Android"); // etc. super.onSaveInstanceState(savedInstanceState); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); boolean myBoolean = savedInstanceState.getBoolean("MyBoolean"); double myDouble = savedInstanceState.getDouble("myDouble"); int myInt = savedInstanceState.getInt("MyInt"); String myString = savedInstanceState.getString("MyString"); }
参考:(下面的链接都非常有价值)
http://blog.csdn.net/ddna/article/details/5123482 http://blog.csdn.net/spare_h/article/details/6659010 http://android.blog.51cto.com/268543/634646/ http://www.th7.cn/Program/Android/201312/162981.shtml http://www.charlesharley.com/2012/programming/views-saving-instance-state-in-android/ http://stackoverflow.com/questions/3542333/how-to-prevent-custom-views-from-losing-state-across-screen-orientation-changes http://stackoverflow.com/questions/14891434/overriding-view-onsaveinstancestate-and-view-onrestoreinstancestate-using-vi https://github.com/CharlesHarley/Example-Android-SavingInstanceState/blob/master/src/com/example/android/savinginstancestate/views/LockCombinationPicker.java
相关文章推荐
- Android Activity的onSaveInstanceState() 和 onRestoreInstanceState()方法
- Android Activity的onSaveInstanceState() 和 onRestoreInstanceState()方法
- Android开发之Activity的onSaveInstanceState()和 onRestoreInstanceState()方法
- View 和 AbsListView中的onSaveInstanceState()方法以及onRestoreInstanceState()方法的使用
- Activity之onSaveInstanceState()和 onRestoreInstanceState()方法
- Android使用详解之onSaveInstanceState和onRestoreInstanceState触发的时机
- [置顶] Activity的onSaveInstanceState()和 onRestoreInstanceState()方法
- android Activity细节(一) onSaveInstanceState()方法使用注意点
- android onSaveInstanceState的使用方法
- onSaveInstanceState 和onRestoreInstanceState的使用方法
- Android使用详解之onSaveInstanceState和onRestoreInstanceState触发的时机
- Activity的onSaveInstanceState()和onRestoreInstanceState()方法
- Android使用详解之onSaveInstanceState和onRestoreInstanceState触发的时机
- android Activity细节(一) onSaveInstanceState()方法使用注意点
- Activity的两个神秘方法onSaveInstanceState() 和 onRestoreInstanceState() .
- onSaveInstanceState()方法使用注意点
- android onSaveInstanceState的使用方法
- Android 中 onSaveInstanceState()使用方法详解
- Android使用详解之onSaveInstanceState和onRestoreInstanceState触发的时机
- onSaveInstanceState()方法使用注意点