回答
在帶有UI的Fragment
中,您經常會將一些View
作爲實例狀態來加速訪問。例如指向您的EditText
的鏈接,因此您不必一直使用findViewById
。
問題是View
保留對Activity
上下文的引用。現在,如果您保留View
,您還保留對該上下文的引用。
如果上下文仍然有效,但典型的保留情況是重新啓動活動,那麼這沒有問題。例如,經常用於屏幕旋轉。活動娛樂將創建一個新的上下文,舊的上下文旨在被垃圾收集。但現在不能垃圾收集,因爲您的Fragment
仍然有一箇舊的參考。
以下示例說明如何不這樣做
public class LeakyFragment extends Fragment {
private View mLeak; // retained
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mLeak = inflater.inflate(R.layout.whatever, container, false);
return mLeak;
}
@Override
public void onDestroyView() {
super.onDestroyView();
// not cleaning up.
}
}
爲了擺脫這個問題,你需要清除onDestroyView
你的UI的所有引用。一旦Fragment
實例被重新使用,您將被要求在onCreateView
上創建一個新的UI。在onDestroyView
之後保留UI也沒有意義。 Ui不會被使用。
在這個例子中的修復纔剛剛改變onDestroyView
到
@Override
public void onDestroyView() {
super.onDestroyView();
mLeak = null; // now cleaning up!
}
而除了保持到View
S變量,你顯然應該不保持引用到Activity
(例如,從onAttach
- 乾淨的onDetach
)或任何Context
(除非它是Application
上下文)。
有任何想法,如何處理,這可能會導致空指針山?我有幾個動畫偵聽器,線程,並且每個人都使用其中一個引用,它在onDestroyView中被取消。所以無論何時我使用其中一個引用,我首先必須檢查null。這非常不方便。 – Tamas
@Tamas Listeners,Threads,...都可以保持引用,只要它們不保留對任何引用「Activity」的引用即可。如果他們有類似的引用和活動重新使用它不會導致任何有效的,所以你必須更新它無論如何。 – zapl
@Tamas示例:http://pastebin.com/8A18kMym你基本上需要傳播'onAttach' /'onDetach'到任何引用上下文和'onCreateView' /'onDestroyView'的任何引用視圖的東西。 – zapl
setRetainInstance(true)
用於在Activity重新創建期間保留動態片段的實例,例如屏幕旋轉或其他配置更改。這並不意味着系統會永遠保留片段。
由於其他原因(例如用戶完成活動(即後退))終止Activity時,Fragment應該有資格進行垃圾回收。
保留耦合到Activity的特定對象時要小心。
注意:雖然你可以返回任何對象,你永遠不應該傳遞是聯繫在一起的活動,如可繪製對象,適配器,一個查看或者某個相關的任何其他對象與上下文。如果這樣做,它會泄漏原始活動實例的所有視圖和資源。 (泄漏資源意味着您的應用程序會保留它們,並且它們不能被垃圾收集,因此可能會丟失大量內存。)
http://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject
您可以在此改變onDestroy()
並調用垃圾收集器。
@Override
public void onDestroy() {
super.onDestroy();
System.gc();
System.gc();
}
有20%的機會可以工作:P 2x'System.gc()'爲了安全嗎?永遠不要依賴'gc()' –
「setRetainInstance」用於在活動重新創建時維護片段的狀態。 根據官方文檔:如果我們使用「setRetainInstance」,片段生命週期的兩個方法將不會被執行(onCreate,onDestroy)。 但是,片段中包含的視圖將被重新創建,這是因爲生命週期將從「onCreateView」執行。 在這些情況下,如果我們在「onSaveInstanceState」中保存了一些數據,我們應該在「onActivityCreated」中而不是在「onCreate」中請求它。
公報信息:https://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)
更多信息:https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en
- 1. 內存泄漏,位圖,碎片
- 2. iOS中的內存保留和泄漏
- 3. 內存泄漏片段trasaction
- 4. 片段內存泄漏
- 5. Android片段內存泄漏
- 6. 使用loadNibNamed會留下內存泄漏
- 7. 標籤/片段和內存泄漏
- 8. 的ctypes和內存泄漏
- 9. Valgrind的和內存泄漏
- 10. 內存泄漏
- 11. 內存泄漏:
- 12. 內存泄漏
- 13. 內存泄漏
- 14. 內存泄漏
- 15. 內存泄漏
- 16. 內存泄漏
- 17. 內存泄漏
- 18. 內存泄漏
- 19. 內存泄漏
- 20. 內存泄漏:
- 21. 內存泄漏
- 22. 內存泄漏
- 23. 內存泄漏
- 24. 內存泄漏
- 25. 內存泄漏
- 26. 內存泄漏
- 27. 內存泄漏
- 28. 大內存頁面和碎片
- 29. C和OpenCV內存泄漏
- 30. 內存泄漏NSMutableArray和NSDictionary
只是爲了記錄的話題,這裏有類似的主題:http://stackoverflow.com/q/11182180/693752 – Snicolas
HTTP://計算器。 com/q/11160412/693752 – Snicolas