What's the Difference Between Commit() and Apply() in Sharedpreferences

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.

  1. It's safe to assume that the statement is valid, because calling exit(0) is an edge-case you should not do normally.
  2. There's no reason to assume that commit will be replaced with apply 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/MainThread

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



Leave a reply



Submit