프래그먼트의 setRetainInstance (boolean) 이해


341

설명서로 시작 :

공공 무효 setRetainInstance (부울 유지)

활동 변경 (예 : 구성 변경)에서 프래그먼트 인스턴스를 유지할지 여부를 제어합니다. 백 스택에없는 프래그먼트에만 사용할 수 있습니다. 설정하면 활동이 다시 작성 될 때 프래그먼트 라이프 사이클이 약간 다릅니다.

  • onDestroy ()는 호출되지 않습니다 (그러나 조각이 현재 활동에서 분리되어 있기 때문에 onDetach ()는 여전히 호출됩니다).
  • 프래그먼트가 다시 생성되지 않으므로 onCreate (Bundle)가 호출되지 않습니다.
  • onAttach (Activity) 및 onActivityCreated (Bundle)이 계속 호출됩니다.

질문이 몇 개 있습니다:

  • 프래그먼트도 뷰를 유지합니까, 아니면 구성 변경시 다시 생성됩니까? "보유"란 정확히 무엇을 의미합니까?

  • 사용자가 활동을 떠날 때 프래그먼트가 파괴됩니까?

  • 백 스택에서 조각으로 작동하지 않는 이유는 무엇입니까?

  • 이 방법을 사용하는 것이 적합한 사용 사례는 무엇입니까?


답변:


348

우선, 보유 조각에 대한 내 게시물 을 확인하십시오 . 도움이 될 수 있습니다.

이제 귀하의 질문에 대답하십시오 :

프래그먼트도 상태를 유지합니까 , 아니면 구성 변경시 다시 생성됩니까? 정확히 "보존"된 것은 무엇입니까?

예, Fragment의 상태는 구성 변경 전체에서 유지됩니다. 특히 "보유"는 구성 변경시 프래그먼트가 파괴 되지 않음을 의미합니다 . 즉, 구성 변경으로 인해 기본 Fragment손상 되더라도 가 유지 됩니다 Activity.

사용자가 활동을 떠날 때 프래그먼트가 파괴됩니까?

Activitys 와 마찬가지로 Fragment메모리 리소스가 부족한 경우 시스템 에서 s가 손상 될 수 있습니다. 구성 변경을 통해 프래그먼트가 인스턴스 상태를 유지하는지 여부는 시스템 Fragment을 종료 한 후 시스템이 파괴되는지 여부에 영향을 미치지 않습니다 Activity. Activity(예 : 홈 버튼을 눌러) 나가면 Fragments가 손상되거나 파괴되지 않을 수 있습니다. Activity뒤로 버튼을 눌러 (따라서을 호출 finish()하고 효과적으로 파기 Activity) 를 떠나면 Activity첨부 된 모든 파일 Fragment도 파기됩니다.

백 스택에서 조각으로 작동하지 않는 이유는 무엇입니까?

거기가 지원되지 않는 이유는 여러 가지 이유가있을 수 있지만 나에게 가장 명백한 이유는이 때문이다 Activity에 대한 참조를 보유 FragmentManager하고,이 FragmentManager가기 backstack을 관리합니다. 즉, 당신이 선택하는 경우에 상관없이 당신의 유지 Fragment들 또는,하지 Activity(따라서 FragmentManager의 가기 backstack)는 구성 변경에 파괴됩니다. 작동하지 않을 수있는 또 다른 이유는 유지 된 조각 유지되지 않은 조각이 동일한 백 스택에 존재할 수 있으면 문제가 발생할 수 있기 때문 입니다.

이 방법을 사용하는 것이 적합한 사용 사례는 무엇입니까?

보존 된 조각은 상태 정보 (특히 스레드 관리)를 활동 인스턴스에 전파하는 데 매우 유용 할 수 있습니다. 예를 들어, 조각은 Thread또는 AsyncTask의 작업을 관리 하는 인스턴스의 호스트 역할을 할 수 있습니다 . 자세한 내용 은이 주제에 대한 내 블로그 게시물 을 참조하십시오.

일반적으로, 나는 유사하게 사용하여 취급 할 onConfigurationChangedActivity당신이 / 구현 올바르게 방향 변경을 처리하기에 너무 게으른 이유만으로 미봉책으로 사용하지 마십시오 .... 필요할 때만 사용하십시오.


37
뷰 객체는 유지되지 않으며 구성 변경시 항상 삭제됩니다.
Markus Junginger

103
내가 알 수있는 한 setRetainInstance(true), FragmentJava 객체와 Java 객체 가 있으면 회전 할 때 파괴 되지 않지만보기 다시 작성됩니다. 즉 onCreatedView()다시 호출한다. 기본적으로 ActivitiesAndroid 1.0부터 작동해야합니다 . 나는 그것을 사용하는 것이 "게으른"것이라고 생각하지 않거나 그것을 사용하는 것이 "적절하지 않다". 사실 나는 이것이 기본값이 아닌 이유 또는 왜 그것을 원하지 않는지 알 수 없습니다.
Timmmm

24
"백 스택에서 조각으로 작동하지 않는 이유는 무엇입니까?"에 대한 설명을 찾았습니다. 이해하기 어렵다. 그러나 어쩌면 나는 바보입니다 :(
HGPB

13
@dierre 활동은 여러 가지 방법으로 파괴 될 수 있습니다. 예를 들어 "뒤로"를 클릭하면 활동이 삭제됩니다. "홈"을 클릭하면 활동이 중지되고 나중에 메모리가 부족하면 언젠가는 파기 될 수 있습니다. 유지 Fragment는 기본 활동을 삭제하고 즉시 다시 작성해야하는 구성 변경에서만 유지됩니다. 활동이 파괴되는 다른 모든 경우에도 보존 된 조각도 파괴됩니다.
Alex Lockwood

3
@AlexLockwood는 다음을 확인하시기 바랍니다 수 : 비록을 setRetainInstance(true)사용, 하나는 여전히 한다 (자신의 지속성 구현 savedInstanceState, 그렇지 않으면 나) 모든 시나리오를 처리 할 수 있기를 : 예를 들어, "홈 키, 회전, 다시 응용 프로그램으로는"생성자 내 조각을 재현 모든 상태 변수가 손실됩니다. 나는 AsyncTaskas 멤버 변수를 가지고 있기 때문에 유지하려는 이유입니다. 이제 작동하려면 작업을 중지하고 상태를 저장하고 사용자가 돌아올 때 다시 시작해야합니다. 결국 이것은 회전을 돕는 빠른 방법이지만 일반적으로 쓸모가 없습니다.
TWiStErRob

28

setRetaininstanceactivity호출하는 동안 인스턴스가 저장되기 때문에 구성 변경으로 인해 사용자 가 삭제되고 다시 생성 된 경우에만 유용 합니다 onRetainNonConfigurationInstance. 즉, 장치를 회전하면 유지 된 조각이 그대로 유지되지만 (파괴 및 재생성되지는 않음) 런타임에서 리소스를 회수하기 위해 활동이 종료되면 아무 것도 남지 않습니다. 뒤로 버튼을 누르고 활동을 종료하면 모든 것이 파괴됩니다.

일반적 으로이 기능을 사용하여 방향 변경 시간을 저장합니다. 저는 서버에서 여러 비트 맵을 다운로드했으며 사용자가 실수로 장치를 회전 할 때 각각 1MB입니다. 모든 다운로드 작업을 다시하고 싶지는 않습니다. 내가 만들 Fragment내 비트 맵을 잡고 관리자와 통화에 추가 setRetainInstance, 모든 비트 맵은 여전히에도 화면 방향이 변경되는 경우.


비트 맵의 ​​홀더처럼 "데이터 전용"프래그먼트 (위젯없이)를 만들거나 해당 프래그먼트도 위젯을 가질 수 있습니까? 프래그먼트에 컨텍스트 / 액티비티와 관련된 것이 포함되어있을 때 메모리 누수가
발생할

프레임 워크가 mActivity참조를 명확하게합니다 . 그러나이 경우 런타임이 조각 인스턴스의 위젯을 지우는 지 여부는 알 수 없습니다. 사용해 보거나 소스 코드를 살펴보십시오.
suitianshi

setRetaininstance를 사용할 수있는 좋은 예
Mu Sa

12

SetRetainInstance (true)는 조각 종류의 생존을 허용합니다. 회전과 같이 구성을 변경하는 동안 구성원이 유지됩니다. 그러나 백그라운드에서 활동이 종료되면 여전히 종료 될 수 있습니다. 백그라운드에서 포함하는 활동이 시스템에 의해 종료 된 경우, instanceState는 onSaveInstanceState를 올바르게 처리 한 시스템에 의해 저장되어야합니다. 다시 말해 onSaveInstanceState가 항상 호출됩니다. SetRetainInstance가 true이고 조각 / 활동이 아직 종료되지 않은 경우 onCreateView가 호출되지 않지만 종료되어 다시 가져 오려고 시도하면 여전히 호출됩니다.

여기에 도움이되는 안드로이드 활동 / 조각 희망에 대한 분석이 있습니다. http://ideaventure.blogspot.com.au/2014/01/android-activityfragment-life-cycle.html


8
화면을 회전 할 때 유지 된 조각에서 onCreateView가 다시 호출되는 것을 분명히보고 있습니다.
aij

이 링크는 자신의 블로그입니까? 그 경우라면 분명히해야합니다.
Flexo

4

setRetainInstance ()-사용되지 않습니다

조각으로 버전 1.3.0-alpha01

Fragments의 setRetainInstance () 메소드는 더 이상 사용되지 않습니다. ViewModel이 도입되면서 개발자는 활동, 조각 및 탐색 그래프와 연관 될 수있는 상태를 유지하기위한 특정 API를 갖게됩니다. 이를 통해 개발자는 유지되지 않은 일반 조각을 사용하고 유지하려는 특정 상태를 분리하여 유지하면서 단일 누출 및 유지 된 상태 (예 : ViewModel 생성자)의 유용한 속성을 유지하면서 일반적인 누수 원인을 피할 수 있습니다. 그리고 onCleared () 콜백을받습니다).


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.