What's the difference between commit() and apply() in SharedPreferences
apply()
was added in 2.3, it commits without returning a boolean indicating success or failure.
commit()
returns true if the save works, false otherwise.
apply()
was added as the Android dev team noticed that almost no one took notice of the return value, so apply is faster as it is asynchronous.
http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#apply()
Difference Between commit and apply in Android SharedPreferences
Commit()
is instantaneous but performs disk writes. If you are on the ui thread you should call apply()
which is asynchronous.
SharedPreferences - apply() vs. commit()
I would expect it to work, as in the documentation it states:
apply()
commits its changes to the in-memory SharedPreferences immediately but starts an asynchronous commit to disk and you won't be notified of any failures.
As you're accessing the same preferences object (is a singleton) you should see a consistent view at all times.
Will SharedPreferences commit() be automatically changed to apply() in Androids code optimization?
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.
- It's safe to assume that the statement is valid, because calling
exit(0)
is an edge-case you should not do normally. - There's no reason to assume that
commit
will be replaced withapply
automatically. If you want to make sure of it, just use the return value.
Why apply() is no faster than commit() in SharedPreferences.Editor
The problem is you're reading back the values from the in-memory
SharedPreference
which you created before.
According to the documentation,
apply() commits its changes to the in-memory SharedPreferences
immediately but starts an asynchronous commit to disk
Therefore, the in-memory SharedPreference
will be updated immediately.
Using both apply() and commit() in sharedpreference
- commit() is instantaneous but performs disk writes.
- commit() - returns boolean value.
- commit() returns true if the save works, false otherwise and blocking
the UI thread until complete action. - apply() was added as the android dev team noticed that most no one
took notice of the return value, so apply is faster. - apply() is asynchronous.
When would SharedPreferences apply() and commit() fail?
Let's take a look at the source code for commit():
public boolean commit() {
MemoryCommitResult mcr = commitToMemory();
SharedPreferencesImpl.this.enqueueDiskWrite(
mcr, null /* sync write on this thread okay */);
try {
mcr.writtenToDiskLatch.await();
} catch (InterruptedException e) {
return false;
}
notifyListeners(mcr);
return mcr.writeToDiskResult;
}
In other words, commit()
will return false if the thread is interrupted while waiting for the disk write to finish, or if the disk write fails for some reason (most likely because the disk was full).
SharedPreferences.edit() without a corresponding commit() or apply() call
If you do not call commit() or apply(), your changes will not be saved.
- Commit() writes the changes synchronously and directly to the file
- Apply() writes the changes to the in-memory SharedPreferences
immediately but begins an asynchronous commit to disk
How does SharedPreferences handle multiple .apply() calls one after the other?
Do they batch the calls in a queue?
No, they don't. SharedPreferences
were developed to perform very basic tasks.
The .apply()
should only be the last statement when working with SharedPreferences
. So you can refactor your code as this
sharedPreference = context.getSharedPreferences("pet-app-sp", Context.MODE_PRIVATE);
editor = sharedPreference.edit();
editor.clear(); //removed apply
editor.putInt(VERSION_NUMBER_PREFERENCE_KEY, versionCode).apply();
You should also know the difference between commit()
and apply()
apply()
was added in 2.3, it commits without returning a boolean indicating success or failure.
commit()
returns true if the save works, false otherwise.
apply()
was added as the Android dev team noticed that almost no one took notice of the return value, so apply is faster as it is asynchronous.
Basically, commit()
writes the changed SharedPreference
value out to persistent storage immediately, on the other hand, apply()
write the changes to the in-memory SharedPreference
immediately and starts an asynchronous commit to disk. That is why in case of apply()
you will not get notified of the failure or success of your changes like in commit()
which returns you the status of your changes. Source
And about the question in comments:
why does the code in the question not work. As in, why do two sequential calls to .apply() not work?
This may sound pretty vague, but sometimes when working inside asynchronous, you can't be sure with output if you yourself aren't controlling the threads or their queue because being asynchronous, there is a valid possibility that the order of two statements can change. That's why even Vladyslav Matviienko(in the comment section of the question) suggested you to use commit()
which is synchronous and automatically calls clear()
or you can use my answer, i.e. by removing the .apply() call.
Check the documentation
You must be thinking why did they move to .apply()
. Sometimes developers end up inserting tons of data via commit()
which is synchronous and ends up freezing UI
/Main
Thread
SharedPreferences.Editor apply() failures
As seen here here, before writing changes to file, SharedPreferences first tries to create a backup file.
If that succeeds:
Attempt to write the file, delete the backup and return true as atomically as possible. If any exception occurs, delete the new file; next time we will restore from the backup.
So, no exceptions will be thrown and SharedPreferences will return to the previous state (because it makes a backup before writing changes to disk). (Although you won't be notified of any failures).
Related Topics
Android List View Inside a Scroll View
Making Textview Scrollable on Android
"R Cannot Be Resolved to a Variable"
Firebase Offline Capabilities and Addlistenerforsinglevalueevent
How to Have Multiple Styles Inside a Textview
Android: View.Setid(Int Id) Programmatically - How to Avoid Id Conflicts
How to Filter a Recyclerview With a Searchview
Fullscreen Activity in Android
How to Avoid Concurrency Problems When Using Sqlite on Android
Error in Launching Avd With Amd Processor
Exception 'Open Failed: Eacces (Permission Denied)' on Android
Android Soft Keyboard Covers Edittext Field
Google Maps Android API V2 - Interactive Infowindow (Like in Original Android Google Maps)
Firebase Data Desc Sorting in Android