我应该在这个静态SharedPreference助手类上进行同步?

时间:2012-11-18 11:48:47

标签: android sharedpreferences synchronized

我创建了一个以静态方式访问SharedPreferences的类。查看AOSP ContextImpl.java的SharedPreferenceImpl,我发现在执行synchronized(this)put时会使用get

我还应该在下面的代码中的某处添加synchronized吗?

public class AppPreferences {
  // Get static SharedPreferences Editor
  private static Editor getEditor(Context ctx) {
    return PreferenceManager.getDefaultSharedPreferences(ctx).edit();
  }
  // Get static SharedPreferences
  private static SharedPreferences getPref(Context ctx) {
    return PreferenceManager.getDefaultSharedPreferences(ctx);
  }
  public static String getUserName(Context ctx, String defaul) {
    return getPref(ctx).getString("user_name", defaul);
  }
  public static void setUserName(Context ctx, String text) {
    getEditor(ctx).putString("user_name", text).commit();
  }
}

1 个答案:

答案 0 :(得分:0)

android.app.ContextImpl中有一个static field

private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
         new HashMap<String, SharedPreferencesImpl>();

(除了private static final HashMap?!/旁边)。
填充here。因此,应用程序中共享相同上下文的所有线程(我已经问here但我仍然不是100%确定)将共享此SharedPreferencesImpl实例的静态映射 - 现在每当您调用edit()时获得一个new EditorImpl instance - 所以在“synchronized(this)”中你在你的问题中提到 this 指的是手头的EditorImpl实例 - 这没什么用 - 它只是同步访问EditorImpl的内部地图。但是(不同的)编辑器在( common SharedPreferencesImpl 实例上同步它们即将修改此(SharedPreferencesImpl)实例时。因此,在commit()例如commitToMemory() called中,同步is on SharedPreferencesImpl.this。请记住,对磁盘的写入按随机顺序排列(请参阅enqueueDiskWriteSo的javadoc,并注意commit中写入内存和写入磁盘之间没有锁定。因此,只要您不依赖于修改顺序并且不依赖于原子检查设置首选项值(需要同步),您应该安全地修改首选项你自己的)
注意我引用的代码是2.3.1_r1 - 希望仍然有效