libgdx/libgdx

AndroidPreferences.flush() has no way to enforce synchronous saving

LobbyDivinus opened this issue · 2 comments

Issue details

Hi, in my game I used to call restart immediately after storing some settings using the Preferences.flush() method. According to its doc

Makes sure the preferences are persisted.

this should work. However, it resulted in the settings not being saved. The reason being that the underlying SharedPreferences.apply() used on Android does not guarantee actual file saving. Instead it only kicks off an asynchronous saving process.

Reproduction steps/code

val pref = Gdx.app.getPreferences("test")
pref.putString("hi", "mom")
pref.flush()
System.exit(0)

Solution

For now my fix is to simply add some waiting time in between flushing and app restart. However, a nicer solution would be to have a Preferences.flush(boolean sync) method that would call SharedPreferences.commit() in case of sync being true on Android.

Version of libGDX and/or relevant dependencies

1.12.1

Please select the affected platforms

  • Android

SharedPreferences handles android lifecycle phase changes automatically. The problem here is you're killing the process which ignores the Android lifecycle and can cause the kind of issues you describe.

You don't need to worry about Android component lifecycles and their interaction with apply() writing to disk. The framework makes sure in-flight disk writes from apply() complete before switching states.

Without knowing the details of your use case, generally speaking, restarting an Android app due to a settings change is not a good practice.

On the other hand SharedPreferences has some limitations that are overcome by some more modern alternatives such as Jetpack DataStore. I think it'd be a nice contribution to add a new alternative (and optional) Android Preferences DataStore based implementation.

Thanks for the response. Well, I guess I have too much static state. At some point it makes sense to just restart the whole app instead of proper cleanup. Though I consider to do it it properly now.