![](/img/trans.png)
[英]Fragment onSaveInstanceState() called after onDestroyView()
[英]onDestroyView For Fragment Never Called After onStop
我的APP確實有多個片段和活動,其中大多數活動都有不同的片段,這是為了讓我的組件可以輕松重復使用。 當我將其他活動加載到活動堆棧時,我遇到了一個問題。
案件
推出了ActivityA - > ActivityB - > ActivityC
所有這些活動都包含不同的片段,但問題是當ActivityB
從ActivityA
啟動時,雖然onStop被調用,但ActivityA
onDestroyView
的片段不會被調用。
當我繼續向堆棧應用添加太多活動時,我的APP允許從一個到另一個的無限數量的導航逐漸拋出OOM異常。
在下面找到我用來將片段添加到片段后棧的代碼。
final android.support.v4.app.FragmentTransaction ft =
fragmentManager.beginTransaction();
if(transaction.mInAnimation != FragmentTransaction.FRAGMENT_NO_ANIMATION &&
transaction.mOutAnimation != FragmentTransaction.FRAGMENT_NO_ANIMATION) {
ft.setCustomAnimations(transaction.mInAnimation, transaction.mOutAnimation);
}
String tag;
if(transaction.isRoot){
clearFragmentStack();
tag = "0";
}else {
tag = fragmentManager.getBackStackEntryCount() + "";
}
final AtomicFragment fragment = transaction.compile();
ft.replace(transaction.mFrameId, fragment, tag);
ft.addToBackStack(tag);
ft.commit();
所以你的問題似乎是“當你繼續向堆棧應用程序添加太多活動時會逐漸拋出OOM異常”,並且你認為原因可能是切換活動時頂層Fragment上沒有調用onDestroyView()
。
OnDestroyView()
首先,當你從Activity1轉到Activity2時,很可能onDestroyView()
不會在Activity1中的Fragment上調用,因為在啟動Activity2之后你沒有在Activity1中調用finish()
。
這意味着您的Activity1在活動后台中很活躍,但已停止(即onStop調用)。 由於Activity1還活着,所以它的backstack和片段也是如此。 Activity1的Backstack頂部的片段也將停止 。 因此,基本上,當您使用“主頁”按鈕將應用程序發送到后台時,Activity1處於與其輸入的狀態類似的狀態。
在其他情況下,當在片段backstack中在其上方添加另一個片段時,在片段上調用onDestroyView()
。 但是,它不了解活動后台/活動任務 。
如果要清除片段的視圖,可以手動執行(即fragmentManager.popbackstack()
或beginTrasaction.remove(...)
),也可以在啟動Activity2后關閉Activity1(即調用finish()
) - 這也將釋放你的內存,並在Activity1的頂部片段上調用onDestroyView()
。
OutOfMemoryException異常
...當我繼續向堆棧應用添加太多活動時,會逐漸引發OOM異常。
很可能OOM崩潰的原因是你的內存中有太多的Activity實例,而不是某些片段上沒有調用onDestroyView()
。 我還假設您有多個相同活動的實例。
在AndroidManifest.xml
聲明您的活動時,請考慮使用android:launchMode="singleTask"
( 引用 )。 這可確保您在給定任務中只有一個特定活動的單個實例。 如果它是由同一個Activity的太多實例嚴格導致的,那么它本身應該修復你的OutOfMemory問題。
這種方法本身意味着您需要進行某些額外的處理,將重用的活動的UI /狀態重置為“干凈”的狀態。 幸運的是,您可以依賴onNewIntent(...)
( 引用 )來檢測何時需要這樣做。
稍后編輯:內存監視器
關於搜索OutOfMemory錯誤的原因:請使用Android內存監視器搜索內存泄漏。 我發現內存泄漏是討厭的小鬼,從一開始就使用內存監視器總是比(知情)猜測更好。
在您的情況下,在使用您的應用程序一段時間后,在執行一些活動開關后,您需要查看內存中是否有特定活動的多個實例(例如,Activity1)。
只記得在進行堆轉儲之前強制垃圾收集器幾次(只有一次是不夠的)。 這是為了確保在某些點上垃圾收集的引用不會出現在轉儲中。
希望這可以幫助
我注意到的簡單解決方案是
onDestroy()
將調用而不是onDestroyView(),以便您可以使用onDestroy()
當您允許從一個活動到另一個活動的無限數量的導航時,每次啟動活動時都會創建一個新的活動實例。 要阻止它多次創建,請僅創建一次活動,以便只創建該活動的一個實例。 為此,請在清單文件中的標記中添加以下行:
<activity android:name=".MainActivity"
android:launchMode="singleTop"/>
嘗試此代碼並將此代碼添加到您的片段中
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onStop() {
super.onStop();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.