在单独的线程中访问SharedPreferences

3

如果您使用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个回答

7
如果您使用apply,那么在单独的线程中编辑共享首选项是多余的。但请注意,您可能不仅仅编辑SharedPreferences。您也可能正在读取它们。
考虑到您代码的性质,我猜测您将其作为“启动器”活动中的第一件事来调用。如果是这样,那么没有其他内容会检索这些SharedPreferences,因此您将从StrictMode获得磁盘读取违规,而不是编辑。
由于您已经有了后台线程,我建议您切换到commit()而不是使用apply()并浪费另一个线程。

3

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

你要做的是典型的检查和更新操作。你需要手动同步这些操作,以防止另一个线程在你的检查和更新之间进行更新。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接