So, I'm facing this weird problem right now. I HAVE to use SharedPreferences.Editor().commit() in my Android app, but, as the documentation here states,
As SharedPreferences instances are singletons within a process, it's safe to replace any instance of commit() with apply() if you were already ignoring the return value.
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.
Basically it is safe to replace commit()
with apply()
if you're not using the return value, BUT, the difference between two as mentioned here, and as warning in Android Studio states, is that commit()
immediately writes the data, BUT apply()
does that asynchronously.
So my problem here is, I'm changing the language in my app, and I want to restart my app after user chooses the language. But, when user chooses the language, the current chosen language is put in SharedPreferences
.
Now, the problem:
Whenever I use apply()
instead of commit()
and restart my app using the code to restart the app here, the changes are not written on the disk, as, when the app restarts, it does not change the current language, as the value from SharedPreference
is not changed, because it is not immediately written on the disk. But, whenever I use commit()
, the changes are immediately written, and the language is successfully changed when the app is restarted.
So, the questions:
How can people who wrote the code for commit()
and apply()
say that it is completely safe to use apply()
instead of commit()
, if there's very big difference, as commit()
writes the data immediately, but apply()
does it in background?
If I build my apk, will the commit()
be replaced by apply()
in code optimization if I'm not using the return value.(I know I can know this by building the release version of the app, but I still won't be sure, because when I use apply()
, it veeery frequently 1/10 times actually does change the value from SharedPreference)
A note:
The problem is, that with Runtime.getRuntime().exit(0)
or System.exit(0)
you'll kill the process and therefore no scheduled async task will execute after.
If you don't intend to change your restart code, you should keep commit
instead of apply
for this instance and suppress the warning.
exit(0)
is an edge-case you should not do normally.commit
will be replaced with apply
automatically. If you want to make sure of it, just use the return value.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With