Sobes.tech
Junior

Proč se při otáčení obrazovky znovu vytváří aktivita?

sobes.tech AI

Odpověď od AI

Když se obrazovka otočí, mění se konfigurace zařízení, například orientace. Android na to reaguje tím, že zničí a znovu vytvoří aktivitu, aby mohl aplikovat potřebné změny v zdrojích, jako jsou layoutové soubory specifické pro portrét nebo krajinu.

Životní cyklus aktivity při otáčení:

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

Pro uložení dat stavu před zničením aktivity se používají:

  • onSaveInstanceState(): uloží malá data do Bundle.

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putString("myKey", "myValue") // Uložení dat
    }
    

    Obnovení v onCreate() nebo onRestoreInstanceState():

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        if (savedInstanceState != null) {
            val myValue = savedInstanceState.getString("myKey") // Obnovení dat
        }
        // ...
    }
    
  • ViewModel: Ukládá data po celou dobu životního cyklu UI-ovladače (Activity/Fragment), i při změně konfigurace. ViewModel přežije zničení aktivity a neztrácí svůj stav.

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

    Použití v aktivitě/fragmentu:

    class MyActivity : AppCompatActivity() {
        private lateinit var viewModel: MyViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
            // Nyní se viewModel.counter zachovává při otáčení
        }
    }
    
  • Uložení dat do SharedPreferences nebo databáze pro trvalejší data.

Aby se zabránilo znovuvytvoření aktivity při otáčení obrazovky, lze určit, že aktivita sama zpracovává změny konfigurace. To se provádí v manifestu přidáním atributu configChanges="orientation|screenSize|screenLayout" k tagu <activity>:

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

V takovém případě místo znovuvytvoření aktivity bude volána metoda onConfigurationChanged():

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    // Ruční zpracování změny konfigurace
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        // Logika pro krajinu
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        // Logika pro portrét
    }
}

Použití configChanges nedoporučuje ve většině případů, protože může vést ke složitostem při správě stavu a zdrojů při různých změnách konfigurace. Preferovaným přístupem je použití ViewModelu pro uchování dat stavu.