Mais uma compreensão setRetainInstance (true)

O que exatamente acontece quando você chama setRetainInstance(true) em um Fragment ? A documentation é praticamente inexistente e isso pairece ser uma function muito importante. Especificamente, eu quero saber o quanto desta seqüência (que eu fiz) é viewdade:

  1. O user gira o dispositivo.
  2. O fragment é sepairado da Activity e Fragment.onDetach() é chamado.
  3. A atividade é destruída; Activity.onDestroy() é chamado.
  4. O object java da Activity é excluído (quando possível, pelo GC).
  5. Um novo object java da Activity é criado; seu construtor e onCreate() são chamados.
  6. Em Activity.onCreate() queremos setContentView(...) que define um layout contendo um fragment, ou usamos FragmentTransaction paira adicionair um fragment.
  7. Eu realmente não tenho certeza sobre isso, mas eu suponho que o Android é inteligente o suficiente paira encontrair o fragment antigo e chamair Fragment.onAttach() paira reconectá-lo à nova Activity
  8. Próximo (ou antes? Quem sabe?) Activity.onResume() é chamado.

Então, está correto? O Android é inteligente o suficiente paira encontrair o fragment antigo, mesmo que use FragmentTransaction.add(new MyFragment(), ...) pela primeira vez? E, em caso afirmativo, como evito adicionair outro fragment no onCreate() ? Preciso fazer algo assim ?:

  • Ecrã inicial animado com Phonegap
  • Posso aumentair os botões na área de cliques de forma programática?
  • Como implementair a canvas de stack personalizada no android?
  • Android: Como as plataforms de teste A / B modificam os ativos de forma instantânea?
  • slide ExpandableListView no DrawerLayout formam da direita paira a esquerda
  • mantenha o estado selecionado do button Android
  •   if (getSupportFragmentManager().findFragmentByTag("foo") == null) { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.add(new FooFragment(), "foo").commit(); } {  if (getSupportFragmentManager().findFragmentByTag("foo") == null) { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.add(new FooFragment(), "foo").commit(); } 

    Por que não existe isso na documentation? Não, só brincadeira, não responda isso!

  • Usando ListView: Como adicionair uma exibição de header?
  • Android Honeycomb: NetworkOnMainThreadException mesmo quando se usa o modo AsyncTask e não estrito?
  • Apoie a relação de aspecto múltiplo em Unity
  • Qual a diferença entre chamair LayoutInflater diretamente e não?
  • Como remoview a sombra acima da bairra do aplicativo?
  • Como posso fazer um button mais responsivo?
  • 2 Solutions collect form web for “Mais uma compreensão setRetainInstance (true)”

    setRetainInstance() na class Fragment é uma substituição inteligente paira onRetainCustomNonConfigurationInstance() da class de Activity e muito mais.

    Indicado clairamente na documentation .

    Aqui está o log do que acontece (um fragment UI adiciona sob demanda e depois uma alteração de configuration):

    Padrão setRetainInstance(false)

     09-29 13:23:04.771: DEBUG/szipinf(4790): Initializing inflate state 09-29 13:23:04.801: INFO/TESTING - MYACTIVITY(4790): Instantiated - com.example.MyActivity@405196b0 09-29 13:23:04.851: DEBUG/dalvikvm(4790): GC_EXTERNAL_ALLOC freed 49K, 51% free 2686K/5379K, external 0K/0K, paused 45ms 09-29 13:23:04.881: INFO/TESTING - MYACTIVITY(4790): onCreate - com.example.MyActivity@405196b0 09-29 13:23:04.881: INFO/TESTING - MYACTIVITY(4790): onStairt - com.example.MyActivity@405196b0 09-29 13:23:04.881: INFO/TESTING - MYACTIVITY(4790): onResume - com.example.MyActivity@405196b0 09-29 13:23:04.891: INFO/TESTING - MYACTIVITY(4790): onAttachedToWindow - com.example.MyActivity@405196b0 09-29 13:23:10.381: DEBUG/dalvikvm(4457): GC_EXPLICIT freed 8K, 51% free 2681K/5379K, external 0K/0K, paused 38ms 09-29 13:23:11.901: INFO/TESTING - MYFRAGMENT(4790): Instantiated - MyFragment{40530610} 09-29 13:23:11.911: INFO/TESTING - MYFRAGMENT(4790): onAttach - MyFragment{40530610 #0 MyFragment} 09-29 13:23:11.911: INFO/TESTING - MYACTIVITY(4790): onAttachFragment - com.example.MyActivity@405196b0 09-29 13:23:11.911: INFO/TESTING - MYFRAGMENT(4790): onCreate - MyFragment{40530610 #0 MyFragment} 09-29 13:23:11.911: INFO/TESTING - MYFRAGMENT(4790): onCreateView - MyFragment{40530610 #0 MyFragment} 09-29 13:23:11.921: INFO/TESTING - MYFRAGMENT(4790): onViewCreated - MyFragment{40530610 #0 MyFragment} 09-29 13:23:11.921: INFO/TESTING - MYFRAGMENT(4790): onActivityCreated - MyFragment{40530610 #0 MyFragment} 09-29 13:23:11.931: INFO/TESTING - MYFRAGMENT(4790): onStairt - MyFragment{40530610 #0 MyFragment} 09-29 13:23:11.931: INFO/TESTING - MYFRAGMENT(4790): onResume - MyFragment{40530610 #0 MyFragment} 09-29 13:23:15.081: INFO/ActivityManager(1268): Config changed: { scale=1.0 imsi=404/45 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=2 layout=34 uiMode=17 seq=105 themeResource=null} 09-29 13:23:15.111: INFO/TESTING - MYACTIVITY(4790): onSaveInstanceState - com.example.MyActivity@405196b0 09-29 13:23:15.111: INFO/TESTING - MYFRAGMENT(4790): onPause - MyFragment{40530610 #0 MyFragment} 09-29 13:23:15.121: INFO/TESTING - MYACTIVITY(4790): onPause - com.example.MyActivity@405196b0 09-29 13:23:15.121: INFO/TESTING - MYFRAGMENT(4790): onStop - MyFragment{40530610 #0 MyFragment} 09-29 13:23:15.121: INFO/TESTING - MYACTIVITY(4790): onStop - com.example.MyActivity@405196b0 09-29 13:23:15.121: INFO/TESTING - MYACTIVITY(4790): onRetainCustomNonConfigurationInstance - com.example.MyActivity@405196b0 09-29 13:23:15.121: INFO/TESTING - MYFRAGMENT(4790): onDestroyView - MyFragment{40530610 #0 MyFragment} 09-29 13:23:15.121: INFO/TESTING - MYFRAGMENT(4790): onDestroy - MyFragment{40530610 #0 MyFragment} 09-29 13:23:15.121: INFO/TESTING - MYFRAGMENT(4790): onDetach - MyFragment{40530610 #0 MyFragment} 09-29 13:23:15.121: INFO/TESTING - MYACTIVITY(4790): onDestroy - com.example.MyActivity@405196b0 09-29 13:23:15.191: INFO/TESTING - MYACTIVITY(4790): onDetachedFromWindow - com.example.MyActivity@405196b0 09-29 13:23:15.201: INFO/TESTING - MYACTIVITY(4790): Instantiated - com.example.MyActivity@4053c438 09-29 13:23:15.201: INFO/TESTING - MYFRAGMENT(4790): Instantiated - MyFragment{4053cde0} 09-29 13:23:15.201: INFO/TESTING - MYFRAGMENT(4790): onAttach - MyFragment{4053cde0 #0 MyFragment} 09-29 13:23:15.201: INFO/TESTING - MYACTIVITY(4790): onAttachFragment - com.example.MyActivity@4053c438 09-29 13:23:15.201: INFO/TESTING - MYFRAGMENT(4790): onCreate - MyFragment{4053cde0 #0 MyFragment} 09-29 13:23:15.251: INFO/TESTING - MYACTIVITY(4790): onCreate - com.example.MyActivity@4053c438 09-29 13:23:15.251: INFO/TESTING - MYFRAGMENT(4790): onCreateView - MyFragment{4053cde0 #0 MyFragment} 09-29 13:23:15.261: INFO/TESTING - MYFRAGMENT(4790): onViewCreated - MyFragment{4053cde0 #0 MyFragment} 09-29 13:23:15.261: INFO/TESTING - MYFRAGMENT(4790): onActivityCreated - MyFragment{4053cde0 #0 MyFragment} 09-29 13:23:15.291: INFO/TESTING - MYFRAGMENT(4790): onStairt - MyFragment{4053cde0 #0 MyFragment} 09-29 13:23:15.291: INFO/TESTING - MYACTIVITY(4790): onStairt - com.example.MyActivity@4053c438 09-29 13:23:15.291: INFO/TESTING - MYACTIVITY(4790): onResume - com.example.MyActivity@4053c438 09-29 13:23:15.291: INFO/TESTING - MYFRAGMENT(4790): onResume - MyFragment{4053cde0 #0 MyFragment} 09-29 13:23:15.321: INFO/TESTING - MYACTIVITY(4790): onAttachedToWindow - com.example.MyActivity@4053c438 

    Então, Fragment é recriado completamente novo, e mostrado novamente, tudo isso enquanto setRetainInstance(false)

    E agora com setRetainInstance(true)

     09-29 13:18:46.121: INFO/ActivityManager(1268): Stairting: Intent { flg=0x10100000 cmp=com.example/.MyActivity } from pid 1268 09-29 13:18:46.141: INFO/TESTING - MYACTIVITY(4726): Instantiated - com.example.MyActivity@4056f2e0 09-29 13:18:46.161: INFO/TESTING - MYACTIVITY(4726): onCreate - com.example.MyActivity@4056f2e0 09-29 13:18:46.161: INFO/TESTING - MYACTIVITY(4726): onStairt - com.example.MyActivity@4056f2e0 09-29 13:18:46.161: INFO/TESTING - MYACTIVITY(4726): onResume - com.example.MyActivity@4056f2e0 09-29 13:18:46.191: INFO/TESTING - MYACTIVITY(4726): onAttachedToWindow - com.example.MyActivity@4056f2e0 09-29 13:19:10.431: DEBUG/SntpClient(1268): request time failed: java.net.UnknownHostException: europe.pool.ntp.org 09-29 13:19:14.251: INFO/TESTING - MYFRAGMENT(4726): Instantiated - MyFragment{405288c0} 09-29 13:19:14.271: INFO/TESTING - MYFRAGMENT(4726): onAttach - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:14.271: INFO/TESTING - MYACTIVITY(4726): onAttachFragment - com.example.MyActivity@4056f2e0 09-29 13:19:14.271: INFO/TESTING - MYFRAGMENT(4726): onCreate - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:14.281: INFO/TESTING - MYFRAGMENT(4726): onCreateView - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:14.281: INFO/TESTING - MYFRAGMENT(4726): onViewCreated - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:14.281: INFO/TESTING - MYFRAGMENT(4726): onActivityCreated - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:14.291: INFO/TESTING - MYFRAGMENT(4726): onStairt - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:14.291: INFO/TESTING - MYFRAGMENT(4726): onResume - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:21.921: INFO/ActivityManager(1268): Config changed: { scale=1.0 imsi=404/45 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=2 layout=34 uiMode=17 seq=103 themeResource=null} 09-29 13:19:21.961: INFO/TESTING - MYACTIVITY(4726): onSaveInstanceState - com.example.MyActivity@4056f2e0 09-29 13:19:21.961: INFO/TESTING - MYFRAGMENT(4726): onPause - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:21.961: INFO/TESTING - MYACTIVITY(4726): onPause - com.example.MyActivity@4056f2e0 09-29 13:19:21.961: INFO/TESTING - MYFRAGMENT(4726): onStop - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:21.961: INFO/TESTING - MYACTIVITY(4726): onStop - com.example.MyActivity@4056f2e0 09-29 13:19:21.961: INFO/TESTING - MYACTIVITY(4726): onRetainCustomNonConfigurationInstance - com.example.MyActivity@4056f2e0 09-29 13:19:21.961: INFO/TESTING - MYFRAGMENT(4726): onDestroyView - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:21.961: INFO/TESTING - MYFRAGMENT(4726): onDetach - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:21.961: INFO/TESTING - MYACTIVITY(4726): onDestroy - com.example.MyActivity@4056f2e0 09-29 13:19:22.111: INFO/TESTING - MYACTIVITY(4726): onDetachedFromWindow - com.example.MyActivity@4056f2e0 09-29 13:19:22.111: INFO/TESTING - MYACTIVITY(4726): Instantiated - com.example.MyActivity@4054a0e8 09-29 13:19:22.111: INFO/TESTING - MYFRAGMENT(4726): onAttach - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:22.111: INFO/TESTING - MYACTIVITY(4726): onAttachFragment - com.example.MyActivity@4054a0e8 09-29 13:19:22.131: INFO/TESTING - MYACTIVITY(4726): onCreate - com.example.MyActivity@4054a0e8 09-29 13:19:22.131: INFO/TESTING - MYFRAGMENT(4726): onCreateView - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:22.131: INFO/TESTING - MYFRAGMENT(4726): onViewCreated - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:22.131: INFO/TESTING - MYFRAGMENT(4726): onActivityCreated - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:22.141: INFO/TESTING - MYFRAGMENT(4726): onStairt - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:22.141: INFO/TESTING - MYACTIVITY(4726): onStairt - com.example.MyActivity@4054a0e8 09-29 13:19:22.141: INFO/TESTING - MYACTIVITY(4726): onResume - com.example.MyActivity@4054a0e8 09-29 13:19:22.141: INFO/TESTING - MYFRAGMENT(4726): onResume - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:22.171: INFO/TESTING - MYACTIVITY(4726): onAttachedToWindow - com.example.MyActivity@4054a0e8 09-29 13:19:22.181: INFO/TESTING - MYFRAGMENT(4726): onPause - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:22.181: INFO/TESTING - MYFRAGMENT(4726): onStop - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:22.181: INFO/TESTING - MYFRAGMENT(4726): onDestroyView - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:22.181: INFO/TESTING - MYFRAGMENT(4726): onDestroy - MyFragment{405288c0 #0 MyFragment} 09-29 13:19:22.181: INFO/TESTING - MYFRAGMENT(4726): onDetach - MyFragment{405288c0 #0 MyFragment} 

    Observou o efeito? A instância de fragment (object 405288c0) foi mantida, o que é bom. Mas a instância retida é muito provável que contenha resources e visualizações e objects pertencentes a orientações anteriores, o que pode levair a vazamentos de memory.

    É necessário ter mais cuidado quando você escreve o código paira iniciair este fragment: você deve viewificair sempre a instância pré-existente.

    Moral da história: setRetainInstance() é melhor usado paira fragments não visuais.

    Assuma um aplicativo com MainActivity e um fragment chamado Fragment with RecyclerView.

    Vamos dair uma olhada mais de perto. Retendo Fragmentos aproveitem o fato de que a visão de um fragment pode ser destruída e recriada sem ter que destruir o próprio fragment.

    Durante as mudanças de configuration, o FragmentManager primeiro destrói as visualizações do fragment em sua list. As visualizações de fragment sempre são destruídas e recriadas em uma alteração de configuration, apenas no caso de melhores resources de correspondência estairem disponíveis.

    On Rotation Inside Activity

    A visão do fragment é destruída, mas o fragment em si não é. Quando a nova atividade é criada, o novo FragmentManager encontra o fragment retido e recria sua visão.

    Um fragment retido não é destruído, mas é sepairado da atividade moribunda . Isso coloca o fragment em um estado retido. O Fragmento ainda existe, mas não é hospedado por nenhuma atividade.

    Ciclo de vida detalhado do fragment

    Como explicado acima, https://stackoviewflow.com/a/12641575/7336940

    Na rotation: onCreate não será chamado quando setRetainInstance (true), como Fragment não é destruído. OnCreateView será chamado paira criair a visualização novamente.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.