Sobes.tech
Junior

Prečo sa aktivita pri otáčaní obrazovky znova vytvára?

sobes.tech AI

Odpoveď od AI

Keď sa obrazovka otočí, mení sa konfigurácia zariadenia, napríklad orientácia. Android na to reaguje zničením a opätovným vytvorením aktivity, aby mohol aplikovať potrebné zmeny v zdrojoch, ako sú layoutové súbory špecifické pre portrét alebo krajinu.

Životný cyklus aktivity pri otáčaní:

  1. onPause()
  2. onStop()
  3. onDestroy()
  4. Systém vytvorí nový exemplár aktivity.
  5. onCreate()
  6. onStart()
  7. onResume()

Na uloženie dát stavu pred zničením aktivity sa používajú:

  • onSaveInstanceState(): uloží malé dáta do Bundle.

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putString("myKey", "myValue") // Uloženie dát
    }
    

    Obnovenie v onCreate() alebo onRestoreInstanceState():

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        if (savedInstanceState != null) {
            val myValue = savedInstanceState.getString("myKey") // Obnovenie dát
        }
        // ...
    }
    
  • ViewModel: Uloží dáta počas celého životného cyklu UI-ovládača (Activity/Fragment), aj pri zmene konfigurácie. ViewModel prežije zničenie aktivity a neztráca svoje stav.

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

    Použitie v aktivite/fragmentu:

    class MyActivity : AppCompatActivity() {
        private lateinit var viewModel: MyViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
            // Teraz sa viewModel.counter zachováva pri otáčaní
        }
    }
    
  • Uloženie dát do SharedPreferences alebo databázy pre trvalejšie údaje.

Aby sa zabránilo opätovnému vytvoreniu aktivity pri otáčaní obrazovky, môžete oznámiť, že aktivita sama spracováva zmeny konfigurácie. To sa robí v manifeste, pridaním atribútu configChanges="orientation|screenSize|screenLayout" k tagu <activity>:

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

V takom prípade namiesto opätovného vytvorenia aktivity bude volaná metóda onConfigurationChanged():

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    // Rukoväť zmeny konfigurácie manuálne
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        // Logika pre krajinu
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        // Logika pre portrét
    }
}

Použitie configChanges sa neodporúča vo väčšine prípadov, pretože môže viesť k zložitostiam pri správe stavu a zdrojov pri rôznych zmenách konfigurácie. Preferovaný prístup je použiť ViewModel na uloženie dát stavu.