Sobes.tech
Junior

Por que a atividade é recriada ao girar a tela?

sobes.tech IA

Resposta da IA

Ao rodar a tela, a configuração do dispositivo muda, por exemplo, a orientação. O Android reage a isso destruindo e recriando a atividade para aplicar as alterações necessárias nos recursos, como ficheiros de layout específicos para orientação retrato ou paisagem.

Ciclo de vida da atividade ao rodar:

  1. onPause()
  2. onStop()
  3. onDestroy()
  4. O sistema cria uma nova instância da atividade.
  5. onCreate()
  6. onStart()
  7. onResume()

Para guardar dados de estado antes de destruir a atividade, usam-se:

  • onSaveInstanceState(): guarda pequenos dados num Bundle.

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putString("myKey", "myValue") // Guardar dados
    }
    

    Restauração em onCreate() ou onRestoreInstanceState():

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        if (savedInstanceState != null) {
            val myValue = savedInstanceState.getString("myKey") // Restaurar dados
        }
        // ...
    }
    
  • ViewModel: guarda dados durante todo o ciclo de vida do controlador de interface de utilizador (Atividade/Fragmento), mesmo quando a configuração muda. O ViewModel sobrevive à destruição da atividade e não perde o seu estado.

    class MyViewModel : ViewModel() {
        var counter = 0
    }
    

    Uso na atividade/fragmento:

    class MyActivity : AppCompatActivity() {
        private lateinit var viewModel: MyViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
            // Agora, viewModel.counter mantém-se ao rodar a tela
        }
    }
    
  • Guardar dados em SharedPreferences ou numa base de dados para dados mais persistentes.

Para evitar a recriação da atividade ao rodar a tela, pode-se declarar que a atividade trata ela própria as mudanças de configuração. Isto faz-se no manifesto, adicionando o atributo configChanges="orientation|screenSize|screenLayout" à tag <activity>:

<activity android:name=".MyActivity"
          android:configChanges="orientation|screenSize|screenLayout">
</activity>

Neste caso, em vez de recriar a atividade, será chamado o método onConfigurationChanged():

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    // Lidar manualmente com a mudança de configuração
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        // Lógica para orientação de paisagem
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        // Lógica para orientação retrato
    }
}

O uso de configChanges não é recomendado na maioria dos casos, pois pode complicar a gestão do estado e recursos em diferentes mudanças de configuração. A abordagem preferida é usar ViewModel para guardar os dados de estado.