t3rse
t3rse

Reputation: 10124

Accessing SharedPreferences On Separate Thread

Is editing shared preferences in a separate thread redundant if you use apply?

I have the following code block in an onCreate method of my MainActivity:

    final MainActivity activityReference = this;

    Executors.newSingleThreadExecutor().execute(new Runnable() {
        @Override
        public void run() {

            // if it is the first time running
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activityReference);
            if(!prefs.getBoolean(MainActivity.FIRST_LOAD, false)) {

                // enable a setting on first run                    

                SharedPreferences.Editor editor = prefs.edit();
                editor.putBoolean(MainActivity.FIRST_LOAD, true);
                editor.apply();
            }

        }
    });

Because the instance of SharedPreferences.Editor is calling the apply method it should be asynchronous but prior to running in a separate thread we still got Strict Mode violations. The violations are StrictModeDiskRead violations so the assumption is that they result from obtaining the SharedPreferences, not calling apply. Additionally it seems as though Samsung devices have this problem almost exclusively.

Upvotes: 3

Views: 7237

Answers (2)

Monstieur
Monstieur

Reputation: 8112

SharedPreferences is thread-safe, not atomic. That only guarantees that the API itself won't crash or go into an undefined state if you access it across threads. It doesn't guarantee anything about the data you're storing in it.

What you're trying to do is a typical check and update. You need to manually sychronize those operations so that another thread doesn't update between your check and update.

Upvotes: 4

CommonsWare
CommonsWare

Reputation: 1007276

Is editing shared preferences in a separate thread redundant if you use apply?

Yes, but bear in mind that you may not only be editing SharedPreferences. You may be reading them as well.

Given the nature of your code, my guess is that you're calling it as one of the first things in your LAUNCHER activity. If so, nothing else will have retrieved those SharedPreferences yet, and so you will get disk-read violations from StrictMode for the reading, not so much the editing.

Since you already have the background thread, I'd switch to commit() rather than use apply() and waste another thread.

Upvotes: 7

Related Questions