2013-02-25 17 views
24

我指的是Why use Fragment#setRetainInstance(boolean)?是用碎片的setRetainInstance(真)真的是一個很好的做法來處理旋轉變化

我之所以問那麼是Activity來處理旋轉,Official Activity Documentation鼓勵我們,讓Activity關機和輪換期間重新啓動

android:configChanges列出活動 將自行處理的配置更改。當運行時發生配置更改時, 活動默認關閉並重新啓動,但使用此屬性聲明 配置將會阻止重新啓動活動 。相反,該活動仍在運行,並調用其onConfigurationChanged()方法。注意:應該避免使用此屬性 ,並僅將其用作最後的手段。請閱讀處理 運行時間更改以瞭解有關如何正確處理由於配置更改而導致的重新啓動 的更多信息。

任何嘗試更改此Activity默認行爲似乎都是不好的做法。爲避免重新啓動時重新加載耗時的數據結構,我們使用onRetainNonConfigurationInstancegetLastNonConfigurationInstance。 - Official Handling Runtime Changes

但是,當涉及處理片段中的旋轉時,Google會給我們不同的建議嗎?他們不希望我們關閉並重新啓動Fragment?

public Object onRetainNonConfigurationInstance()

此方法已被廢棄在代替API級別13.使用新片段API setRetainInstance(布爾值);通過Android兼容性軟件包,舊款 平臺也可以使用此功能。

  1. 爲什麼谷歌鼓勵我們關停和旋轉過程中重新啓動活動,但鼓勵我們旋轉過程中保持片段?
  2. 如果setRetainInstance(true)擅長處理輪換,Google爲什麼不將它作爲Fragment的默認行爲?

回答

29
  • 配置更改:當突然屏幕變得更廣泛,高度(典型橫向)少得多,這是易於爲可視組件以更新其顯示和更智能地使用可用的屏幕。配置更改的另一個示例是用戶滑動硬件鍵盤,更改設備語言等。爲什麼要重新啓動:

    • Android組件支持聲明性佈局,您加載了一堆XML佈局,並從那裏開始工作。查找每個視圖並實時重新安排/更新它將是一團糟,更不用說所有事件處理程序和其他自定義View代碼的重新佈線。它更容易重新加載另一堆佈局文件。另外,在Android中,活動的種類活在系統的擺佈之中,所以自然而然,活動生命週期是如此設計(並推薦)的,它能隨時按需重新創建自己,就像它在它被摧毀之前。這種模式適用於所有的重新啓動,這也歸因於配置更改。如果你讓你的活動和片段能夠維持一個永恆的狀態,那麼配置的改變就不是什麼大問題。

    • 保留狀態數據(模型),而不是顯示它的東西(UI和視圖)。

  • setRetainInstance(真):建議只對與不持有任何東西任何參考片段,將要在旋轉重新使用。這意味着你不應該在任何持有上下文,視圖等的片段上使用它。典型的Visual片段可以。但對於持有像運行線程,AsyncTasks,數據集合,加載資產,獲取結果等對象的碎片,這是非常有用的。這種方法有助於使用非可視碎片作爲可拆卸的持有者,用於活動的非依賴於上下文的對象。

+0

是的忘記了爲什麼它不聰明的使用視圖,但上下文泄漏是答案。 – Warpzit 2013-02-25 12:03:11

+1

**「只能與不包含任何將在循環中重新創建的引用的片段一起使用。」**我不太確定這是否100%準確。如果保留的片段在'onActivityCreated(Bundle)'中設置了對父Activity的引用(這將在每次配置更改後在保留的片段中調用),那麼這應該不足以確保保留的'Fragment'從來沒有提到一箇舊的「活動」? – 2013-04-22 00:10:12

+3

@AlexLockwood如果你看源代碼,'FragmentManager'設置一個片段的'mActivity'字段爲其在attach時的父活動,並且當該片段被分離時,也將其設置回null **。在可由'getActivity()'訪問的片段中。因此,並不總是需要存儲對父活動的另一個引用,並且如果這樣做,則必須在分離時清除/釋放它。誠然,如果你足夠小心以確保你不會泄漏上下文引用,你可以以任何方式使用它。我的目的是阻止在任何Fragment上無意識地使用'setReatainInstance()'。 – 2013-04-22 04:52:00

4

因爲你誤解了它的用法。 setRetainInstance(true)只能用於像獨奏元素/模塊的片段。處理套接字等的片段沒有真正受益於被保留的GUI。帶有GUI的碎片應該不會使用setRetainInstance(true)。此外,任何進入後臺的碎片都不應該使用setRetainIstance(true)

你可以把它推廣到任何只處理數據/連接等的片段應該使用setRetainInstance(true)。但是有很多不同的方法來使用片段,這不會從setRetainInstance(true)中受益。

+1

支持你的想法的任何來源? Google Android文檔沒有特別針對UI和非UI片段。 – 2013-02-25 11:58:24

+0

如果你看看setRetainInstance上的google引用(true),它至少不會與backstack一起使用。鏈接:http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean) – Warpzit 2013-02-25 12:01:12

相關問題