Começando com a documentação:
public void setRetainInstance (retenção booleana)
Controle se uma instância de fragmento é retida na recriação da atividade (como em uma alteração na configuração). Isso só pode ser usado com fragmentos que não estão na pilha de trás. Se definido, o ciclo de vida do fragmento será ligeiramente diferente quando uma atividade for recriada:
- onDestroy () não será chamado (mas onDetach () ainda será, porque o fragmento está sendo desanexado de sua atividade atual).
- onCreate (Bundle) não será chamado, pois o fragmento não está sendo recriado.
- onAttach (Activity) e onActivityCreated (Bundle) ainda serão chamados.
Eu tenho algumas questões:
O fragmento também mantém sua visão, ou isso será recriado na alteração da configuração? O que exatamente significa "retido"?
O fragmento será destruído quando o usuário sair da atividade?
Por que não funciona com fragmentos na pilha traseira?
Quais são os casos de uso em que faz sentido usar esse método?
Respostas:
Primeiro de tudo, confira meu post sobre fragmentos retidos. Isso pode ajudar.
Agora, para responder às suas perguntas:
Sim, o
Fragment
estado do será retido durante a alteração da configuração. Especificamente, "retido" significa que o fragmento não será destruído nas alterações de configuração. Ou seja, a retençãoFragment
será mantida mesmo se a alteração na configuração fizer com que o subjacenteActivity
seja destruído.Assim como
Activity
s,Fragment
s pode ser destruído pelo sistema quando os recursos de memória estão baixos. Se seus fragmentos mantêm seu estado de instância nas alterações de configuração, não terá efeito se o sistema destruirá os sistemasFragment
assim que você sairActivity
. Se você sair doActivity
(ou seja, pressionando o botão home), osFragment
s podem ou não ser destruídos. Se você sairActivity
pressionando o botão voltar (assim, chamandofinish()
e destruindo efetivamente oActivity
), todos osActivity
s anexadosFragment
também serão destruídos.Provavelmente, existem várias razões pelas quais não é suportado, mas a razão mais óbvia para mim é que o
Activity
detém uma referência aoFragmentManager
eFragmentManager
gerencia o backstack. Ou seja, não importa se você optar por manter seusFragment
ou não, oActivity
(e, portanto, oFragmentManager
backstack) será destruído em uma alteração na configuração. Outra razão pela qual isso pode não funcionar é que as coisas podem ficar complicadas se os fragmentos retidos e os não retidos puderem existir no mesmo backstack.Fragmentos retidos podem ser bastante úteis para propagar informações de estado - especialmente gerenciamento de encadeamentos - entre instâncias de atividade. Por exemplo, um fragmento pode servir como host para uma instância de
Thread
ouAsyncTask
, gerenciando sua operação. Veja minha postagem no blog sobre este tópico para obter mais informações.Em geral, eu o trataria da mesma forma que o uso
onConfigurationChanged
com umActivity
... não o use como um bandaid apenas porque você é muito preguiçoso para implementar / lidar com uma alteração de orientação corretamente. Use-o somente quando precisar.fonte
setRetainInstance(true)
, oFragment
objeto java e todo o seu conteúdo não são destruídos na rotação, mas a exibição é recriada. Isso éonCreatedView()
chamado novamente. É basicamente o jeito que deveria funcionarActivities
desde o Android 1.0. Eu não acho que seja "preguiçoso" usá-lo, ou usá-lo não é "adequado". Na verdade, não consigo ver por que não é o padrão ou por que você iria querer isso.Fragment
são retidos apenas nas alterações de configuração, onde a atividade subjacente deve ser destruída e recriada imediatamente. Em todos os outros casos em que a atividade é destruída, os fragmentos retidos também serão destruídos.setRetainInstance(true)
usado, ainda é necessário implementar sua própria persistência (savedInstanceState
ou não) para poder lidar com todos os cenários: por exemplo, "tecla home, girar, voltar ao aplicativo" recria meu fragmento com o construtor chamada, perdendo todas as variáveis de estado. Eu tenho umaAsyncTask
variável como membro, é por isso que quero reter, agora, se quiser que funcione, sou forçado a interromper a tarefa, salvar o estado e retomar quando o usuário voltar. Portanto, apesar de tudo, essa é apenas uma maneira rápida de ajudar na rotação, mas, de outra forma, inútil em geral.setRetaininstance
só é útil quando vocêactivity
é destruído e recriado devido a uma alteração na configuração porque as instâncias são salvas durante uma chamada paraonRetainNonConfigurationInstance
. Ou seja, se você girar o dispositivo, os fragmentos retidos permanecerão lá (eles não serão destruídos e recriados.) Mas quando o tempo de execução interrompe a atividade para recuperar recursos, nada resta. Quando você pressiona o botão Voltar e sai da atividade, tudo é destruído.Normalmente, eu uso essa função para salvar a orientação, alterando o Time. Diga que tenho que baixar um monte de Bitmaps do servidor e cada um tem 1 MB, quando o usuário acidentalmente gira o dispositivo, certamente não quero fazer todo o trabalho de download novamente. Crio uma
Fragment
retenção dos meus bitmaps e os adiciono ao gerente e à chamadasetRetainInstance
. Todos os bitmaps ainda estão lá, mesmo que a orientação da tela seja alterada.fonte
mActivity
referência para você. Mas não sei se o tempo de execução também limparia widgets na instância de fragmento nesse caso. Por favor, experimente ou mergulhe no código fonte.SetRetainInstance (true) permite que o tipo de fragmento sobreviva. Seus membros serão retidos durante a alteração da configuração, como rotação. Mas ainda pode ser morto quando a atividade é morta em segundo plano. Se a atividade que contém o plano de fundo for eliminada pelo sistema, o instanceState deverá ser salvo pelo sistema que você tratou no SaveInstanceState corretamente. Em outra palavra, o onSaveInstanceState sempre será chamado. Embora onCreateView não seja chamado se SetRetainInstance for true e o fragmento / atividade ainda não for eliminado, ele ainda será chamado se for eliminado e tentar ser recuperado.
Aqui estão algumas análises da atividade / fragmento do Android, espero que ajude. http://ideaventure.blogspot.com.au/2014/01/android-activityfragment-life-cycle.html
fonte
setRetainInstance () - Descontinuado
Como fragmentos versão 1.3.0-alpha01
fonte
setRetainInstance (boolean) é útil quando você deseja ter algum componente que não esteja vinculado ao ciclo de vida da atividade. Essa técnica é usada, por exemplo, pelo rxloader para "manipular o ciclo de vida da atividade do Android para o Observable do rxjava" (que eu encontrei aqui ).
fonte