在单独的线程上访问SharedPreferences

时间:2014-08-06 18:50:05

标签: android multithreading sharedpreferences

如果您使用apply,是否在单独的线程中编辑共享首选项是多余的?

我在MainActivity的onCreate方法中有以下代码块:

    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();
            }

        }
    });

因为SharedPreferences.Editor的实例正在调用apply方法,所以它应该是异步的,但在单独的线程中运行之前,我们仍然会遇到Strict Mode违规。违规是StrictModeDiskRead违规,因此假设它们来自获取SharedPreferences,而不是调用apply。此外,似乎三星设备几乎完全有这个问题。

2 个答案:

答案 0 :(得分:2)

  

如果您使用apply,是否在单独的线程中编辑共享首选项是多余的?

是的,但请记住,您可能正在编辑SharedPreferences。你也可能正在阅读它们。

鉴于您的代码的性质,我的猜测是您将其称为LAUNCHER活动中的第一件事。如果是这样,那么其他任何内容都无法检索到SharedPreferences,因此您将从StrictMode获取读取的磁盘读取,而不是编辑。

由于您已经拥有后台线程,我将切换到commit()而不是使用apply()并浪费另一个线程。

答案 1 :(得分:1)

SharedPreferences是线程安全的,而不是原子的。这只能保证如果您跨线程访问API本身不会崩溃或进入未定义状态。它并不保证您存储在其中的数据。

您尝试做的是典型的检查和更新。您需要手动同步这些操作,以便另一个线程不会在您的检查和更新之间进行更新。