Android Activity Fragment 狀態保存
首先查閱這幾篇文章,了解acticity和fragment的保存過程。
[譯]Android Activity 和 Fragment 狀態保存與恢復的最佳實踐
Android Fragment+ViewPager 組合,一些你不可不知的注意事項
Android Fragment使用(三) Activity, Fragment, WebView的狀態保存和恢復
附帶activity和fragment的生命周期圖,看后應該比較容易理解。
看完后基本了解原理了,這里要將要點總結一下:
1.Back stack中的fragment,只是View的銷毀和重建, 其本身并沒有被重建,并且成員變量也沒有被清除,所以這種情況不用做任何保存操作系統自動保存,當然listview和recycleview的數據需重新設置回去,setAdapter,也是下面的第3點
2.fragment + viewpage 時注意使用FragmentPagerAdapter 和 FragmentStatePagerAdapter 這個兩個函數的不同
3.在使用fragment+recycleview或activity+recycleview時如何恢復原來狀態和數據,其實也不是那么復雜,recycleview的位置系統將自動保存,你只需重新設置adapter的數據即可,注意:如果是fragment一定要在onCreateView()函數恢復,而且要在view組件完成Listener后恢復;如果是activiy則在onRestoreInstanceState(),同樣要在view組件完成Listener后恢復;
recycleview能自動保存狀態是因為實現了以下方法(系統自帶),第三方view必須實現以下方法才能讓系統正確保存狀態
<pre>
public class CustomView extends View {
...
@Override
public Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
// Save current View's state here
return bundle;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(state);
// Restore View's state here
}
...
}
</pre>
Activity恢復狀態情況:
<pre>
public class MainActivity extends AppCompatActivity {
// These variable are destroyed along with Activity
private int someVarA;
private String someVarB;
...
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("someVarA", someVarA);
outState.putString("someVarB", someVarB);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
someVarA = savedInstanceState.getInt("someVarA");
someVarB = savedInstanceState.getString("someVarB");
}
...
}
</pre>
Fragment恢復狀態情況:
<pre>
public class MainFragment extends Fragment {
// These variable are destroyed along with Activity
private int someVarA;
private String someVarB;
...
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("someVarA", someVarA);
outState.putString("someVarB", someVarB);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
someVarA = savedInstanceState.getInt("someVarA");
someVarB = savedInstanceState.getString("someVarB");
}
...
}
</pre>
保存服務器加載的數據:
<pre>
public class MainFragment extends Fragment {
...
private String dataGotFromServer;
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("dataGotFromServer", dataGotFromServer);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dataGotFromServer = savedInstanceState.getString("dataGotFromServer");
}
...
}
</pre>
3.在activity和fragment的生命周期函數中的onSaveInstanceState()不是每次新建或重建都會運行,只有在系統將它銷毀或關閉屏幕時才會運行,在activity中的onRestoreInstanceState()只有重建才運行
4.組件必須設置id屬性,如EditText 或者 TextView,只要設置了 android:freezeText="true",其他組建有id就行
所以請不要在Fragment或activity的 onSaveInstanceState 方法中保存 View 狀態。