旋转屏幕时,activity会被重建(也可以控制其不被重建)
这个时候,onSaveInstanceState会在onStop前被调用,和onPause之间没有固定时序。Activity在被重建的时候,会在onStart后调用onRestoreInstanceState,并把onSaveInstance中保存的bundle给onRestoreInstanceState(?)和onCreate。
此外,onSaveInstanceState和onRestoreInstanceState中,还有系统自动做的恢复工作。如文本框用户输入的数据,ListView的滚动位置。原因是每个View自身也有onSaveInstanceState和onRestoreInstanceState两个方法。在Activity的onSaveInstaceState调用的时候,他会委托Window,Window又会委托DecorView,然后分发,遍历所有的子元素的onSaveInstaceState方法。数据恢复也是这样。
TextView的onSaveInstanceState方法,保存了文本选中位置和文本
@Override public Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); // Save state if we are forced to final boolean freezesText = getFreezesText(); boolean hasSelection = false; int start = -1; int end = -1; if (mText != null) { start = getSelectionStart(); end = getSelectionEnd(); if (start >= 0 || end >= 0) { // Or save state if there is a selection hasSelection = true; } } if (freezesText || hasSelection) { SavedState ss = new SavedState(superState); if (freezesText) { if (mText instanceof Spanned) { final Spannable sp = new SpannableStringBuilder(mText); if (mEditor != null) { removeMisspelledSpans(sp); sp.removeSpan(mEditor.mSuggestionRangeSpan); } ss.text = sp; } else { ss.text = mText.toString(); } } if (hasSelection) { // XXX Should also save the current scroll position! ss.selStart = start; ss.selEnd = end; } if (isFocused() && start >= 0 && end >= 0) { ss.frozenWithFocus = true; } ss.error = getError(); if (mEditor != null) { ss.editorState = mEditor.saveInstanceState(); } return ss; } return superState; }
onRestoreInstanceState和onCreate中恢复的区别,onCreate中需要进行判空,如果没有重写onSaveInstaceState,那Bundle就是空的。而onRestoreInstanceState中,只要执行到这个方法,那bundle就肯定不为空,所以就不需要进行判断。推荐用onRestoreInstanceState。
还有一种就是资源不足强杀的情况。想要后台运行的东西,最好是放在service里,因为只有四大组件存在的地方,优先级较高,不容易被强杀。
如何才能在系统配置改变的时候不重建Activity呢?需要在配置文件中给Activity指定 configChanges, configChanges=“orientation|screenSize”这样就不会因为屏幕旋转而重建了。