activity被回收,fragment恢復處理
onCreate中不要重複建立fragment,通過tag去獲得figment即可。
從谷歌開源專案中得到的的啟示,原始碼:
原始碼摘自:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewResId()); if (getIntent().hasExtra(Intent.EXTRA_TITLE)) { setTitle(getIntent().getStringExtra(Intent.EXTRA_TITLE)); } final String customTitle = getIntent().getStringExtra(Intent.EXTRA_TITLE); setTitle(customTitle != null ? customTitle : getTitle()); if (savedInstanceState == null) { mFragment = onCreatePane(); mFragment.setArguments(intentToFragmentArguments(getIntent())); getFragmentManager().beginTransaction() .add(R.id.root_container, mFragment, "single_pane") .commit(); } else { mFragment = getFragmentManager().findFragmentByTag("single_pane"); } }
com.google.samples.apps.iosched.ui.SimpleSinglePaneActivity
自己精簡一下就是:
public class MainActivity extends AppCompatActivity { private BlankFragment mFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState == null) { mFragment = new BlankFragment(); getSupportFragmentManager().beginTransaction() .add(R.id.root_container, mFragment, "single_pane") .commit(); } else { mFragment = (BlankFragment) getSupportFragmentManager().findFragmentByTag("single_pane"); } Log.e("MainActivity", "savedInstanceState=" + savedInstanceState + " mFragment=" + mFragment); } }
列印了兩個Log,一個是首次建立,另一個是回收了之後建立。
11-22 12:55:43.940 24433-24433/com.example.baidu.test E/MainActivity: savedInstanceState=null mFragment=BlankFragment{585c98a id=0x7f0b0055 single_pane}
11-22 12:57:36.576 24433-24433/com.example.baidu.test E/MainActivity: savedInstanceState=Bundle[{android:viewHierarchyState=Bundle[mParcelledData.dataSize=680], android:support:測試的時候可以設定手機【不保留活動】,這樣可以快速的模擬回收的情況,小米手機有這個功能。
Activity被回收,系統為什麼會儲存Fragment呢?來分析一下FragmentActivity原始碼:
/** * Save all appropriate fragment state.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);//這裡儲存了Fragment資料
}
if (mPendingFragmentActivityResults.size() > 0) {
outState.putInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG, mNextCandidateRequestIndex);
int[] requestCodes = new int[mPendingFragmentActivityResults.size()];
String[] fragmentWhos = new String[mPendingFragmentActivityResults.size()];
for (int i = 0; i < mPendingFragmentActivityResults.size(); i++) {
requestCodes[i] = mPendingFragmentActivityResults.keyAt(i);
fragmentWhos[i] = mPendingFragmentActivityResults.valueAt(i);
}
outState.putIntArray(ALLOCATED_REQUEST_INDICIES_TAG, requestCodes);
outState.putStringArray(REQUEST_FRAGMENT_WHO_TAG, fragmentWhos);
}
}
從原始碼中得知,當Activity呼叫onSaveInstanceState方法的時候,會儲存當前Activity裡面的所有Fragment,儲存在了一個Bundle裡,key就是FRAGMENTS_TAG。
其實這個Bundle會在Activity恢復的時候傳給onCreate,這就是為什麼onSaveInstanceState不是null了。 有人會問什麼時候會呼叫onSaveInstanceState方法?用最簡潔的一句話:當Activity不可見的時候就會執行nSaveInstanceState。例如被另一個Activity覆蓋,按Home鍵回到桌面等等。當然你主動結束Activity不會執行。呼叫onSaveInstanceState儲存的不只是fragment,還儲存了View的狀態,只儲存了帶id的View的狀態,不帶id不會儲存的。 其實回收之後恢復是很麻煩的,得到了Fragment後,你會發現成員變數並沒有恢復,只有View某些狀態被恢復了,如果完全重現被回收那一刻的所有狀態,還需要考慮在Fragment裡面重寫onSaveInstanceState方法,來儲存一些資料,呵呵,工作量不小啊,非特殊情況下,我不建議這麼做。 我一般的做法都是重新建立Activity和Fragment:
public class MainActivity extends AppCompatActivity {
static final String FRAGMENTS_TAG = "android:support:fragments";
private BlankFragment mFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
//刪除儲存的Fragment,也可以重寫onSaveInstanceState方法不讓其儲存
if (savedInstanceState != null) {
savedInstanceState.putParcelable(FRAGMENTS_TAG, null);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFragment = new BlankFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.root_container, mFragment, "single_pane")
.commit();
}
}
你可以記住重要的關鍵資訊,來恢復這個Activiy。例如當前Activity是一篇文章,你只需要在onSaveInstanceState儲存文章id,等恢復的時候直接根據id從伺服器拉取就好了。
如果你的Activity在啟動時的Intent裡面有文章id,那就簡單了,在回收恢復的時候,直接這樣仍然得到文章id:String id = getIntent().getStringExtra("article_id");,這樣根本不用你主動儲存。使用Intent的時候必須序列化的原因:只有被序列化的物件和基本資料型別才可以儲存在磁碟上,這樣記憶體被幹掉,仍然可以將他們從磁碟上恢復到記憶體中。
相關推薦
activity被回收,fragment恢復處理
例如activity放在後臺一段時間,當activity被回收之後,再重新進入activity的時候,會重新呼叫onCreate(),並且savedInstanceState不再是null,因此可以判斷出是否被回收。 onCreate中不要重複建立fragment,通過
關於fragment,activity被回收之後重新恢復
當記憶體不足的時候位於後臺的應用會被系統回收掉,只是保留著任務棧,再次進入的時候會恢復它們。 要注意的地方有:系統只會把ui相關的東西存起來和恢復,其他的一些成員變數都不會管。 會把生命週期和建立一樣重新走一遍,這個時候得注意那些不是從onCreat這樣的生命週期方法中獲得
activity被回收後,點選Tab無法切換fragment
1、原因:當activity在後臺並且記憶體不足時,系統會把activity給回收掉,但也會儲存部分(不是全部)資訊用於下次頁面恢復。這樣會導致下次進入頁面後佈局或資料錯亂,並且點選底部Tab無法切換fragment。 2、解決方法: (1)方法一:註釋掉sup
Activity被回收掉之後的網路請求回撥處理方法詳解
想起寫這麼一篇博文的前提是上週去面試了一家公司,其中有這麼一個問題印象深刻,結合當時在網上看到的解決辦法我就說了一個錯誤答案,結果當場就被面試官給指出了錯誤,所以回來後和我的領導一起討論了這麼一個問題,他提出了一個很好地解決思路,於是乎我便寫了這麼一段程式
Activity被回收導致被繫結Fragment呼叫getActivity()拋空指標異常
當系統記憶體不足,Fragment的宿主Activity被回收的時候,Fragment的例項並沒有隨之被回收。Activity被系統回收時,會主動呼叫onSaveInstance()方法來儲存檢視層(
Activity被回收掉之後的網路回撥處理
早上來到公司剛開啟電腦,就被叫到會議室,召開緊急會議,線上出現重大bug,根據線上日誌統計,崩潰率上升了0.3個百分點(我們專案是集成了騰訊Bugly統計日誌,有興趣的同學可以去了解下)。 這個可不得了,聽說領導被老闆叫過去訓了好久,領導憋了一肚子火,我們的日
Activity在後臺被回收,這個時候觸發showDialog,窗體洩露,WindowManager.BadTokenException
今天在友盟上看到一個崩潰日誌,如下: android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] is not valid; is y
程式後臺Activity被回收後再次啟動fragment失效問題
/////////////////2016/07/01///////////////////// /////////////////by xbw////////////////////////// /////////////////環境 eclipse///////////////// 先上個圖,
當activity改變時,我們如何處理它
速度 change 假設 IT super conf In develop aras 用戶和系統觸發-的事件,可能造成一個activity狀體的改變。這個文檔描述了一些常見的情況,和如何去處理這些改變。 原網站:https://developer.android.googl
桌面的Internet圖示被刪除,如何恢復
桌面的Internet圖示被刪除,如何恢復 有時候桌面的Internet圖示被刪除了,一時又不知如何還原。下面簡單介紹幾種方法。 方法一:在桌面右擊,屬性,桌面,自定義桌面,勾選Internet,確定。當然有人會說,我的自定義桌面裡沒有Internet選項,這是由於系統的兩
系統排錯2:若mbr載入程式被破壞,如何恢復?
系統排錯 若mbr載入程式被破壞,如何恢復? (1)檢視系統版本和boot載入程式所在分割槽 ##檢視系統版本 [[email protected] ~]# hostnamectl ##檢視boot載入程式所在分割槽 [[email protect
後臺的activity被系統自動回收的話,怎麼在回到介面的時候恢復資料
Activity的狀態通常情況下系統會自動儲存的,只有當我們需要儲存額外的資料時才需要使用到這樣的功能。 通常情況: 呼叫onPause()和onStop()方法後的activity例項仍然存在
Activity巢狀多個fragment時,onResume的處理
問題:當Activity裡有多個fragment時,其中fragmentA根據需求,需要在onResume時需要做請求資料等操作,但是如果直接在fragmentA裡的onResume裡寫東西,當從其他頁面返回到fragmentB和fragmentC時,fragmentA裡
android Fragment與Activity交互,互相發數據(附圖具體解釋)
oncreate @+ targe save inflate find enter 提交 ransac 筆者最近看官方training。發現了非常多實用又好玩的知識。當中。fragment與Activity通信就是一個。 fragment與Activity通信主要
回收站被清空了,如何恢復數據?
展現 進入 edi 點擊 專業 類型 選項 回收 教程 不知道大家是否跟小編一樣,有定期清理回收站的習慣,但是如果回收站有重要文件但是已經清空,那麽如何把刪除的文件恢復回來呢?因為文件制作的時間過長,建議用專業的數據恢復軟件進行嘗試。在用EasyRecovery數據恢復軟件
一個Activity中多個Fragment,個別fragment實現沉浸式狀態列
如上圖,同一個activity(NoActionBar)有多個fragment的情況下,只有"我的"模組需要設定為沉浸式的狀態列,而其他fragmen
任務排程框架quartz使用總結(異常處理,解決恢復後多次排程處理)
任務排程框架quartz使用總結(異常處理,解決恢復後多次排程處理) 首先先說說什麼是排程框架,大白話所謂的排程框架你可以把它看成一個定時任務管理框架,並且quartz框架是多執行緒的, quartz最主要的三大基本特性: (1)排程器&nbs
Go 語言的下一個大版本:Go 2.0 被安排上了(全面相容1.X,改進錯誤處理和泛型這兩大主題)
今年 8 月 Go 開發團隊公佈了 Go 2.0 的設計草案,包括錯誤處理和泛型這兩大主題。現在備受矚目的 Go 2.0 又有了新動向 —— 昨日 Go 開發團隊在其官方部落格表示,Go 2 已經被安排上了!目前 Go 2 已進入確定變更提案的階段,並公佈了提案評估流程。 廢話不多說,先
Go 語言的下一個大版本:Go 2.0 被安排上了(全面兼容1.X,改進錯誤處理和泛型這兩大主題)
.org leader utf8 驅動 cleanup 周期 一份 早期 下一個 今年 8 月 Go 開發團隊公布了 Go 2.0 的設計草案,包括錯誤處理和泛型這兩大主題。現在備受矚目的 Go 2.0 又有了新動向 —— 昨日 Go 開發團隊在其官
監控硬盤與普通硬盤有什麽分別,被刪除視頻恢復方法。
發生 添加 臺式機 用戶 視頻恢復 嘗試 慢啟動 啟動 錄制 硬盤對於每一位用戶而言都不陌生,不管是DIY裝機還是日常安防監控都有硬盤的身影,隨著PC用戶對硬件需求的提升,我們生活中出現了機械硬盤、固態硬盤等多種存儲設備。 其中,相信每一玩家在購買大容量機械硬盤的過程中都會