簡體   English   中英

OnStroy上的onDestroyView片段永遠不會被調用

[英]onDestroyView For Fragment Never Called After onStop

我的APP確實有多個片段和活動,其中大多數活動都有不同的片段,這是為了讓我的組件可以輕松重復使用。 當我將其他活動加載到活動堆棧時,我遇到了一個問題。

案件
推出了ActivityA - > ActivityB - > ActivityC

所有這些活動都包含不同的片段,但問題是當ActivityBActivityA啟動時,雖然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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM