環(huán)境描述:java7+android studio2.2+sdk14
背景描述:目前主流的應(yīng)用主頁(yè)一般是一個(gè)MainActivity托管幾個(gè)fragment田藐。我的主頁(yè)MainActivity繼承自FragmentActivity,其托管四個(gè)fragment居触,假設(shè)是FragmentA,FragmentB,FragmentC票罐,來(lái)回切換不同的視圖本缠。在fragment要通過(guò)getActivity來(lái)和activity進(jìn)行通訊;默認(rèn)顯示是fragmentA
問(wèn)題描述:當(dāng)操作執(zhí)行到FragmentB時(shí)逞度,此時(shí)按下home鍵將應(yīng)用放置于后臺(tái)悍手,或者是此時(shí)點(diǎn)擊了qq消息進(jìn)入了qq從而將應(yīng)用置于后臺(tái),此時(shí)再次回到該應(yīng)用中會(huì)發(fā)現(xiàn)MainActivity重新初始化了悠轩,而fragment的視圖并沒(méi)有被銷(xiāo)毀间狂,導(dǎo)致MainActivity重新初始化后出現(xiàn)視圖混亂重合的問(wèn)題。也就是FragmentA的視圖被重建并顯示火架,而fragmentB的視圖并沒(méi)有被銷(xiāo)毀掉鉴象,這兩個(gè)fragment的視圖重合了。這是為什么呢
問(wèn)題分析:原來(lái)MainActivity切換到后臺(tái)之后何鸡,由于內(nèi)存不夠纺弊,此MainActivity被系統(tǒng)回收了,一段時(shí)間之后回到該應(yīng)用程序骡男,Activity被重新實(shí)例化了淆游,它將調(diào)用自身的onSaveInstanceState方法來(lái)恢復(fù)其中view的狀態(tài)和數(shù)據(jù)。而Activity被系統(tǒng)銷(xiāo)毀時(shí)隔盛,它將調(diào)用這個(gè)方法將其中的view的數(shù)據(jù)和狀態(tài)等保存起來(lái)以便重新初始化時(shí)進(jìn)行現(xiàn)場(chǎng)恢復(fù)犹菱。這里涉及到一個(gè)比較深層次的問(wèn)題:activity的生命周期調(diào)用順序問(wèn)題(發(fā)生這種情況是屬于異常生命周期調(diào)用,此處不做詳解吮炕,可參考我的另外一篇博客)腊脱;我們都知道,正常情況下acitivity的生命周期將執(zhí)行第一個(gè)方法時(shí)oncreate(Bundle saveInstanceState),其中參數(shù)saveInstanceState!=null時(shí)龙亲,activity將恢復(fù)現(xiàn)場(chǎng)(恢復(fù)之前與用戶交互時(shí)的界面狀態(tài)和表單中輸入的數(shù)據(jù)等)虑椎,從而導(dǎo)致了這個(gè)問(wèn)題的出現(xiàn),知道了問(wèn)題的原因就好處理了俱笛;
```
@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 =newString[mPendingFragmentActivityResults.size()];
for(inti =0;i
requestCodes[i] =mPendingFragmentActivityResults.keyAt(i);
fragmentWhos[i] =mPendingFragmentActivityResults.valueAt(i);
}
```
根據(jù)源碼可以看出:當(dāng)activity被銷(xiāo)毀時(shí)重建捆姜,其上的view的狀態(tài)和數(shù)據(jù)會(huì)被保存,以便數(shù)據(jù)恢復(fù)迎膜。
處理方法:在Main中重寫(xiě)protected void onSaveInstanceState(Bundle outState);如下
/**
* 當(dāng)activity銷(xiāo)毀時(shí)不保存其內(nèi)部的view的狀態(tài)
*@paramoutState
*/
@Override
public voidonSaveInstanceState(Bundle outState) {
//將super調(diào)用取消即可泥技,表明當(dāng)意外(比如系統(tǒng)內(nèi)存吃緊將應(yīng)用殺死)發(fā)生我不需要保存Fragmentde狀態(tài)和數(shù)據(jù)等
//super.onSaveInstanceState(outState);
}