Activity与多个fragment的之间的相爱想杀
踩到這個礦坑:同一個activity管理多個fragment的時候遇到下面的異常
java.lang.IllegalStateException
Can not perform this action after onSaveInstanceState
??
?
官方文檔說明:http://developer.android.com/reference/android/app/FragmentTransaction.html#commitAllowingStateLoss()
commitAllowingStateLossadded in API level 11 int commitAllowingStateLoss () Like commit() but allows the commit to be executed after an activity's state is saved.
This is dangerous because the commit can be lost if the activity needs to later be restored from its state, so this should only be used for cases where it is okay for the UI state to change unexpectedly on the user.
?
大家都知道Activity的執(zhí)行destory()方法之前會先執(zhí)行一個方法onSaveInstanceState(),這個方法就是保存activity在銷毀之前保存臨時數(shù)據(jù)的,以此來防止數(shù)據(jù)丟失。
那么也就是說onSaveInstanceState()執(zhí)行之后你還要執(zhí)行commit()就會報上面的錯。
通俗的說就像你去趕動車一樣,都已經(jīng)停止檢票了,你還一直在刷票機上一直刷,肯定是刷不過的啊,此時肯定要尋求其他的解決辦法。
那么解決辦法就是把commit()方法替換成commitAllowingStateLoss()就ok。
下面貼出來騰訊bugly平臺為我們整理的解決方案,不得不說大平臺人才多,技術(shù)6
#2875 java.lang.IllegalStateException Can not perform this action after onSaveInstanceState解決方案 狀態(tài)異常。 java.lang.IllegalStateException異常產(chǎn)生的原因及解決辦法 錯誤類型大致為以下幾種: java.lang.IllegalStateException:Cannot forward a response that is already committed IllegalStateException:response already commited IllegalStateException:getOutputStream() has already been called for this request ………… ========================================================= IllegalStateException: Can not perform this action after onSaveInstanceState: #解決辦法:onSaveInstanceState方法是在該Activity即將被銷毀前調(diào)用,來保存Activity數(shù)據(jù)的,如果在保存玩狀態(tài)后 再給它添加Fragment就會出錯。解決辦法就是把commit()方法替換成 commitAllowingStateLoss() ========================================================= 錯誤原因:該異常表示,當前對客戶端的響應已經(jīng)結(jié)束,不能在響應已經(jīng)結(jié)束(或說消亡)后再向客戶端(實際上是緩沖區(qū))輸出任何內(nèi)容。Object is no longer valid to operate on. Was it deleted by another thread?該異常表示,realmObject對象在其他線程已被刪除,在這個線程中使用的時候拋出的異常。具體分析:首先解釋下flush(),我們知道在使用讀寫流的時候數(shù)據(jù)先被讀入內(nèi)存這個緩沖區(qū)中, 然后再寫入文件,但是當數(shù)據(jù)讀完時不代表數(shù)據(jù)已經(jīng)寫入文件完畢,因為可能還有一部分仍未寫入文件而留在內(nèi)存中,這時調(diào)用flush()方法就會把緩沖區(qū)的數(shù)據(jù)強行清空輸出,因此flush()的作用就是保證緩存清空輸出。response是服務端對客戶端請求的一個響應,其中封裝了響應頭、狀態(tài)碼、內(nèi)容等,服務端在把response提交到客戶端之前,會向緩沖區(qū)內(nèi)寫入響應頭和狀態(tài)碼,然后將所有內(nèi)容flush。
這就標志著該次響應已經(jīng)committed(提交)。對于當前頁面中已經(jīng)committed(提交)的response,就不能再使用這個response向緩沖區(qū)寫任何東西(注:同一個頁面中的response.XXX()是同一個response的不同方法,只要其中一個已經(jīng)導致了committed,那么其它類似方式的調(diào)用都會導致 IllegalStateException異常)。 參考:http://my.oschina.net/guhai2004/blog/187041,https://github.com/realm/realm-java/issues/1206 補充另一種異常情況: 我這里的異常是: java.lang.IllegalStateException Can't change tag of fragment d{e183845 #0 d{e183845}}: was d{e183845} now d{e183845 #0 d{e183845}} 經(jīng)查,我在顯示fragment的代碼中使用了: fragment.show(getSupportFragmentManager, fragment.toString()); 而這里是因為兩次toString()結(jié)果不同,導致不同的tag指向的是同一個fragment。 獲取fragment的tag的正確方法應該是使用其提供的fragment.getTag()方法。===================================================== 補充異常: java.lang.IllegalStateException Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 37 path $.data 錯誤原因:該異常是由于服務器錯誤返回的JSON字符串和服務器正常下時返回的JSON字符串結(jié)構(gòu)不同,導致利用Gson解析的時候報了一個異常:本該去解析集合卻強制去解析對象所致. 解決辦法:在使用Gson解析JSON時try cash一下,不報錯按照正常邏輯繼續(xù)解析,報異常則處理為請求失敗邏輯即可. ======================================================
Fragment彈出回退棧的方法
void popBackStack()
彈出堆棧中的一個并且顯示,類似按下返回鍵的操作;
popBackStack(String tag,int flags)
-
tag可以為null或者相對應的tag,flags只有0和1(POP_BACK_STACK_INCLUSIVE)兩種情況
-
如果tag為null,flags為0時,彈出回退棧中最上層的那個fragment。
-
如果tag為null ,flags為1時,彈出回退棧中所有fragment。
-
如果tag不為null,那就會找到這個tag所對應的fragment,flags為0時,彈出該
fragment以上的Fragment,如果是1,彈出該fragment(包括該fragment)以
上的fragment。
popBackStack(int id,int flags)
- 與popBackStack(String tag,int flags)類似,找到id代表的fragment,然后執(zhí)行一樣的操作
popBackStackImmediate(int id, int flags)
popBackStackImmediate(String name, int flags)
popBackStackImmediate()
這幾個方法類似以上的方法,只不過這幾個在內(nèi)部調(diào)用時會立即彈出
?
很多時候我們都以為fragment入棧后,譬如 依次入棧 fragment A ,B ,C ,D,
然后彈出B fragment,在回退棧里并不是我們想象的只剩下 D C A ,而是D C null
A,所以使用FragmentManager.getFragments(),然后拿List< Fragment >里的
對象時特別要注意判空。
如下圖:
?
轉(zhuǎn)載于:https://www.cnblogs.com/zhang-cb/p/7194085.html
總結(jié)
以上是生活随笔為你收集整理的Activity与多个fragment的之间的相爱想杀的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。