理解Fragment的setRetainInstance(boolean)

本文翻譯自:Understanding Fragment's setRetainInstance(boolean)

Starting with the documentation: 從文檔開始:

public void setRetainInstance (boolean retain) public void setRetainInstance(boolean retain)

Control whether a fragment instance is retained across Activity re-creation (such as from a configuration change). 控制是否在活動重新創建(例如從配置更改)中保留片段實例。 This can only be used with fragments not in the back stack. 這隻能用於不在後棧中的片段。 If set, the fragment lifecycle will be slightly different when an activity is recreated: 如果設置,則在重新創建活動時,片段生命週期會略有不同:

  • onDestroy() will not be called (but onDetach() still will be, because the fragment is being detached from its current activity). onDestroy()不會被調用(但是onDetach()仍然會被調用,因爲片段正在與其當前活動分離。
  • onCreate(Bundle) will not be called since the fragment is not being re-created. 因爲片段沒有被重新創建,所以不會調用onCreate(Bundle)。
  • onAttach(Activity) and onActivityCreated(Bundle) will still be called. onAttach(Activity)和onActivityCreated(Bundle)仍將被調用。

I have some questions: 我有一些問題:

  • Does the fragment also retain its view, or will this be recreated on configuration change? 片段是否也保留其視圖,還是會在配置更改時重新創建? What exactly does "retained" mean? “保留”究竟是什麼意思?

  • Will the fragment be destroyed when the user leaves the activity? 當用戶離開活動時,片段是否會被銷燬?

  • Why doesn't it work with fragments on the back stack? 爲什麼它不適用於後端堆棧上的碎片?

  • Which are the use cases where it makes sense to use this method? 哪個是使用此方法有意義的用例?


#1樓

參考:https://stackoom.com/question/kuzk/理解Fragment的setRetainInstance-boolean


#2樓

First of all, check out my post on retained Fragments. 首先,查看關於保留碎片的帖子 It might help. 它可能有所幫助。

Now to answer your questions: 現在回答你的問題:

Does the fragment also retain its view state, or will this be recreated on configuration change - what exactly is "retained"? 片段是否也保留其視圖狀態,或者是否會在配置更改時重新創建 - 究竟是什麼“保留”?

Yes, the Fragment 's state will be retained across the configuration change. 是的, Fragment的狀態將在配置更改中保留。 Specifically, "retained" means that the fragment will not be destroyed on configuration changes. 具體而言,“保留”意味着在配置更改時不會破壞該片段。 That is, the Fragment will be retained even if the configuration change causes the underlying Activity to be destroyed. 也就是說,即使配置更改導致底層Activity被銷燬, Fragment也會被保留

Will the fragment be destroyed when the user leaves the activity? 當用戶離開活動時,片段是否會被銷燬?

Just like Activity s, Fragment s may be destroyed by the system when memory resources are low. 就像Activity s一樣,當內存資源不足時,系統可能會破壞Fragment Whether you have your fragments retain their instance state across configuration changes will have no effect on whether or not the system will destroy the Fragment s once you leave the Activity . 在您離開Activity ,是否讓碎片在配置更改中保留其實例狀態不會影響系統是否會破壞Fragment If you leave the Activity (ie by pressing the home button), the Fragment s may or may not be destroyed. 如果您離開Activity (即按下主頁按鈕),可能會或可能不會銷燬Fragment If you leave the Activity by pressing the back button (thus, calling finish() and effectively destroying the Activity ), all of the Activity s attached Fragment s will also be destroyed. 如果您通過按後退按鈕離開Activity (因此,調用finish()並有效地銷燬Activity ),所有Activity附加的Fragment也將被銷燬。

Why doesn't it work with fragments on the back stack? 爲什麼它不適用於後端堆棧上的碎片?

There are probably multiple reasons why it's not supported, but the most obvious reason to me is that the Activity holds a reference to the FragmentManager , and the FragmentManager manages the backstack. 可能有多種原因導致它不受支持,但最明顯的原因是Activity包含對FragmentManager的引用,而FragmentManager管理backstack。 That is, no matter if you choose to retain your Fragment s or not, the Activity (and thus the FragmentManager 's backstack) will be destroyed on a configuration change. 也就是說,無論您是否選擇保留FragmentActivity (以及FragmentManager的Backstack)都將在配置更改時被銷燬。 Another reason why it might not work is because things might get tricky if both retained fragments and non-retained fragments were allowed to exist on the same backstack. 它可能不起作用的另一個原因是因爲如果允許保留的片段非保留的片段都存在於同一個後臺上,事情可能會變得棘手。

Which are the use cases where it makes sense to use this method? 哪個是使用此方法有意義的用例?

Retained fragments can be quite useful for propagating state information — especially thread management — across activity instances. 保留的片段對於跨活動實例傳播狀態信息(尤其是線程管理)非常有用。 For example, a fragment can serve as a host for an instance of Thread or AsyncTask , managing its operation. 例如,片段可以充當ThreadAsyncTask實例的主機,從而管理其操作。 See my blog post on this topic for more information. 有關詳細信息,請參閱關於此主題的博客文章

In general, I would treat it similarly to using onConfigurationChanged with an Activity ... don't use it as a bandaid just because you are too lazy to implement/handle an orientation change correctly. 一般來說,我會把它與使用onConfigurationChangedActivity一樣對待...不要僅僅因爲你太懶而無法正確實現/處理方向更改而將其用作onConfigurationChanged Only use it when you need to. 只在需要時使用。


#3樓

SetRetainInstance(true) allows the fragment sort of survive. SetRetainInstance(true)允許片段生存。 Its members will be retained during configuration change like rotation. 其成員將在配置更改期間保留,如輪換。 But it still may be killed when the activity is killed in the background. 但是當活動在後臺被殺死時它仍然可能被殺死。 If the containing activity in the background is killed by the system, it's instanceState should be saved by the system you handled onSaveInstanceState properly. 如果後臺中的包含活動被系統殺死,那麼它的instanceState應該由您在onSaveInstanceState上正確處理的系統保存。 In another word the onSaveInstanceState will always be called. 換句話說,將始終調用onSaveInstanceState。 Though onCreateView won't be called if SetRetainInstance is true and fragment/activity is not killed yet, it still will be called if it's killed and being tried to be brought back. 雖然如果SetRetainInstance爲true且片段/活動尚未被殺死,則不會調用onCreateView,但如果它被殺死並被試圖被帶回,它仍然會被調用。

Here are some analysis of the android activity/fragment hope it helps. 以下是對android活動/片段的一些分析希望它有所幫助。 http://ideaventure.blogspot.com.au/2014/01/android-activityfragment-life-cycle.html http://ideaventure.blogspot.com.au/2014/01/android-activityfragment-life-cycle.html


#4樓

setRetaininstance is only useful when your activity is destroyed and recreated due to a configuration change because the instances are saved during a call to onRetainNonConfigurationInstance . setRetaininstance僅在由於配置更改而銷燬和重新創建activity時纔有用,因爲在調用onRetainNonConfigurationInstance期間保存了實例。 That is, if you rotate the device, the retained fragments will remain there(they're not destroyed and recreated.) but when the runtime kills the activity to reclaim resources, nothing is left. 也就是說,如果您旋轉設備,保留的片段將保留在那裏(它們不會被銷燬並重新創建。)但是當運行時殺死活動以回收資源時,不會留下任何內容。 When you press back button and exit the activity, everything is destroyed. 當您按下後退按鈕並退出活動時,一切都將被銷燬。

Usually I use this function to saved orientation changing Time.Say I have download a bunch of Bitmaps from server and each one is 1MB, when the user accidentally rotate his device, I certainly don't want to do all the download work again.So I create a Fragment holding my bitmaps and add it to the manager and call setRetainInstance ,all the Bitmaps are still there even if the screen orientation changes. 通常我使用這個功能來保存方向更改Time.Say我從服務器下載了一堆Bitmaps,每個都是1MB,當用戶不小心旋轉他的設備時,我當然不想再做所有的下載工作了。所以我創建一個Fragment保存我的位圖並將其添加到管理器並調用setRetainInstance ,即使屏幕方向發生變化,所有位圖仍然存在。


#5樓

setRetainInstance(boolean) is useful when you want to have some component which is not tied to Activity lifecycle. 當您想要一些與Activity生命週期無關的組件時, setRetainInstance(boolean)非常有用。 This technique is used for example by rxloader to "handle Android's activity lifecyle for rxjava's Observable" (which I've found here ). 這種技術例如由rxloader用於“處理Android的rxjava的Observable的活動生命週期”(我在這裏找到)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章