本系列文章一共三篇,第一张讲activity正常生命周期,第二篇讲activity异常的生命周期
第二篇
当横屏切换为竖屏的时候,activity对象默认是会从新创建的,当然这个我们可以阻止它从新创建,(列如xml中写死屏幕方法,也可以代码设置,自行百度)
横竖屏切换(或者内存不够系统回收)
oncreate, onstart, onresume,onpasue,onstop,ondestroy,oncreate,onstart ,onresume.
需要了解两个方法
1, onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState)
调用时机、onstop 之前 ,这个方法的主要作用就是给我们保存之前的数据,我们可以在这个方法中去保存我们需要的数据,
2,onRestoreInstanceState(Bundle savedInstanceState)
调用时机;条件activity不是正常销毁,从新创建在onstart之后,这个方法回调的时候可以从bundle拿到我们之前保存的数据,当然也可从oncreate(Bundle savedInstanceState)方法中拿参数,但是如果正常创建bundle则会为空,所以需要判断才能用
其实google建议我们用这个方法onRestoreInstanceState(Bundle savedInstanceState),只有异常销毁之后从新创建才会回调此方法
延伸,这种异常回收保存数据机制,view中也有 看textview源码
@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; }
textview数据恢复的源码
@Override public void onRestoreInstanceState(Parcelable state) { if (!(state instanceof SavedState)) { super.onRestoreInstanceState(state); return; } SavedState ss = (SavedState) state; super.onRestoreInstanceState(ss.getSuperState()); // XXX restore buffer type too, as well as lots of other stuff if (ss.text != null) { setText(ss.text); } if (ss.selStart >= 0 && ss.selEnd >= 0) { if (mText instanceof Spannable) { int len = mText.length(); if (ss.selStart > len || ss.selEnd > len) { String restored = ""; if (ss.text != null) { restored = "(restored) "; } Log.e(LOG_TAG, "Saved cursor position " + ss.selStart + "/" + ss.selEnd + " out of range for " + restored + "text " + mText); } else { Selection.setSelection((Spannable) mText, ss.selStart, ss.selEnd); if (ss.frozenWithFocus) { createEditorIfNeeded(); mEditor.mFrozenWithFocus = true; } } } } if (ss.error != null) { final CharSequence error = ss.error; // Display the error later, after the first layout pass post(new Runnable() { public void run() { if (mEditor == null || !mEditor.mErrorWasChanged) { setError(error); } } }); } if (ss.editorState != null) { createEditorIfNeeded(); mEditor.restoreInstanceState(ss.editorState); } }这种保存的机制大概原理就是,activity异常回收的时候,会调用onsaveinstace方法,然后委托window 去保存数据,window再去委托decorview去保存数据,最后decorview在一一遍历子元素 去保存数据,典型的委托思想这样数据就全部保存了