Android线程安全SharedPreferences

时间:2012-02-03 07:02:48

标签: java android concurrency thread-safety semaphore

我不确定我现在是否真的需要这个,但如果我的应用程序扩展了,我可以看到这种可能性。我基本上有一个SharedPreferences的包装器,它从SharedPreferences中提取一些值并将它们捆绑到一个对象中。它还需要一个对象并使用它来更新首选项。我想让它成为线程安全的,但我想用信号量来尝试它。我的SharedPreferences包装器将从getSyncedPrefManager()获得对以下类的引用。然后,它会调用aquireLock(),然后调用getPref(),执行其工作,然后调用releaseLock()。这看起来像什么东西可以工作或我离开基地?

public class SyncedPreferenceManager {
    private final static SyncedPreferenceManager me =
                               new SyncedPreferenceManager();

    private SharedPreferences prefs;
    private static Semaphore mutex;

    public static SyncedPreferenceManager getSyncedPrefManager(){
        return me;
    }

    private SyncedPreferenceManager(){
        mutex = new Semaphore(1, true);
    }

    public SharedPreferences getPref(Context caller){
        if(prefs == null)
            prefs = PreferenceManager.getDefaultSharedPreferences(caller);
        return prefs;
    }

    public boolean aquireLock(){
        try {
            mutex.acquire();
        } catch (InterruptedException e) {
            return false;
        }
        return true;
    }

    public boolean releaseLock(){
        mutex.release();
        return true;
    }

}

3 个答案:

答案 0 :(得分:0)

同步部分应足以达到此目的。通常,从偏好中保存/加载值没有性能问题(那里没有那么多的值) 我也怀疑,你根本不需要它。首选项通常在活动启动时加载,或者在暂停时保存(无论如何,这种类型都是有问题的,当时只有一个活动正在启动或停止)

在我的说法中,热切地阅读优先权,并且只有在专用设置活动暂停时才会保存。在这种情况下,我不需要任何相互排斥。

我还开发了一个小包装器库,它允许简单的编组/解组首选项到对象属性中:

https://github.com/ko5tik/andject

答案 1 :(得分:0)

你可能不喜欢这个答案。

您在这里没有使用正确的系统。 SharedPreferences用于存储简单的首选项。仅仅因为你能做到这一点并不意味着你应该这样做。你基本上试图让SharedPreferences成为不是的东西。你可以添加所有这些花哨的锁定,但它不会阻止某人稍后进入它下面并意外地将其炸毁。

如果您发现自己需要这些功能,那么您应该直接使用sqlite。毫无疑问,您可以向SharedPreferences添加同步(我确信它在某种程度上是安全的,因为它已经设计了事务/提交模型)但在我看来似乎重新发明了轮子。

答案 2 :(得分:0)

您始终可以在SharedPreferences.Editor中进行更改,并使用apply()以原子方式应用更改。

editor.apply()可从API级别9获得。

此处的文档:http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#apply()