Sobes.tech
Junior

Dlaczego aktywność jest ponownie tworzona podczas obracania ekranu?

sobes.tech AI

Odpowiedź od AI

Przy obróceniu ekranu zmienia się konfiguracja urządzenia, na przykład orientacja. Android reaguje na to, niszcząc i ponownie tworząc aktywność, aby zastosować niezbędne zmiany w zasobach, takie jak pliki układu specyficzne dla orientacji portretowej lub landscape.

Cykl życia aktywności przy obróceniu:

  1. onPause()
  2. onStop()
  3. onDestroy()
  4. System tworzy nową instancję aktywności.
  5. onCreate()
  6. onStart()
  7. onResume()

Aby zapisać dane stanu przed zniszczeniem aktywności, używa się:

  • onSaveInstanceState(): zapisuje niewielkie dane w Bundle.

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

    Odzyskiwanie w onCreate() lub onRestoreInstanceState():

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        if (savedInstanceState != null) {
            val myValue = savedInstanceState.getString("myKey") // Odzyskiwanie danych
        }
        // ...
    }
    
  • ViewModel: przechowuje dane przez cały cykl życia kontrolera UI (Activity/Fragment), nawet gdy zmienia się konfiguracja. ViewModel przetrwa zniszczenie aktywności i nie traci swojego stanu.

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

    Użycie w aktywności/fragmencie:

    class MyActivity : AppCompatActivity() {
        private lateinit var viewModel: MyViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
            // Teraz viewModel.counter jest zachowany przy obróceniu
        }
    }
    
  • Zapisywanie danych w SharedPreferences lub bazie danych dla danych bardziej trwałych.

Aby uniknąć ponownego tworzenia aktywności przy obróceniu ekranu, można zadeklarować, że aktywność sama obsługuje zmiany konfiguracji. Robi się to w manifeście, dodając atrybut configChanges="orientation|screenSize|screenLayout" do tagu <activity>:

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

W takim przypadku zamiast tworzenia aktywności, wywoływana jest metoda onConfigurationChanged():

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    // Ręczne obsługiwanie zmiany konfiguracji
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        // Logika dla orientacji landscape
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        // Logika dla orientacji portrait
    }
}

Użycie configChanges nie jest zalecane w większości przypadków, ponieważ może utrudniać zarządzanie stanem i zasobami podczas różnych zmian konfiguracji. Zalecanym podejściem jest użycie ViewModel do przechowywania danych stanu.