Home > Back-end >  Can I trust my global variables to always be preserved during screen rotation? (Android / Kotlin)
Can I trust my global variables to always be preserved during screen rotation? (Android / Kotlin)

Time:01-21

Is it bad practice to use Global variables instead of bundles to preserve state between screen rotations?

I really like just using global variables to keep state. But since everything suggests using bundles, should I do that? I don't know what pitfalls I could be thinking of.

Here is a snippet of code that demonstrates global variables dont change. I have to check that the LEVEL_DEFS list is 0 before adding to it, otherwise every screen rotation adds duplicate levels (where I originally assumed I would have to re-add the levels after rotation) `

val LEVEL_FILES = arrayOf("levels/lv1.txt", "levels/lv2.txt", "levels/lv3.txt")

val LEVEL_DEFS = mutableListOf<LevelDefinition>()

fun getAllLevels(context: Context): MutableList<Level> {
    if (LEVEL_DEFS.size == 0) {
        for (filename in LEVEL_FILES) {
            LEVEL_DEFS.add(LevelDefinition(getTextFileString(context, filename)))
        }
    }
}

`

When I google screen rotation, all the results suggest that you have to use a bundle to save state.

I also asked chat gpt-3, which insisted that I must use a bundle to save the state during rotation.

Yet, it is clear to me that global variables do not change during rotation. I have used many simulated and real devices and they all behave the same way.

CodePudding user response:

Global variables persist as long as your application is running - however when it is in the background you have no guarantee that the Android OS won't stop and re-start your application (which would lose any global or static variables). Once your application goes to the background, you can no longer be certain they will stick around.

What you have posted looks like it would be fine though if you only access it through the getAllLevels method (since it re-creates it when needed). However, if you are adding levels somewhere else, those could be lost.

If you want to be able to add levels, one possible solution would be to load the data from SharedPreferences inside getAllLevels when the list is empty - and update the SharedPreferences any time levels are added.

CodePudding user response:

Your global variables will live as long as their scope is in memory, so it depends where you're storing them - if they're at the top level (e.g. defined in the top level of a file, or in an Application component) that state will exist until the process is destroyed.

If your state is stored in an Activity, then that Activity will be destroyed on rotation, so typically you'd use the Bundle passed into onSaveInstanceState to store any data you need, and then restore it when appropriate.

If your app is in the background, its process can be destroyed at any time by the system - in that case, you'd lose your global variable state. For an Activity, those save state lifecycle methods would be called, so you'd still store in the Bundle and receive that Bundle when the app is opened again. The process will have been destroyed, but if you're set up to store and restore that state, you'll handle it just like with a rotation. (This is a different situation to the user actually closing the app, which considers the next time it's opened to be a "fresh start" and doesn't provide any stored state.)

You can also use View Models to store state, which survive rotation but require using SavedStateHandle to behave like the Bundle and survive process death (but again, not actual restarts). More info about your options for storing this transient state here.


So what this means is it depends exactly what you're storing, how long it needs to stick around, and if it's allowed to be destroyed when the app is in the background. That last one is usually a "no" which makes global variables a bad fit in most cases.

You'll need some way to persist that data (e.g. SharedPreferences) and at that point you may as well use that as your state, rather than storing it there and in a variable. Up to you though! Persisting data is also how you'd handle state surviving fresh start app restarts too, e.g. storing a high score that shouldn't disappear when the user closes the app.

(Also I'm not sure what asking a chatbot for advice is worth, no matter how much it "insists"! But that's a whole other topic)

  • Related