1

SharedPreferences アクセスを静的に保持するクラスを作成しました。AOSP ContextImpl.java の SharedPreferenceImpl を見ると、実行時に使用されていることがsynchronized(this)わかります。putget

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

1 に答える 1

0

静的フィールドandroid.app.ContextImplがあります

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

(脇private static final HashMap?! /脇)。これはここ
に移入されます。したがって、同じコンテキストを共有するアプリケーション内のすべてのスレッド (ここで尋ねましたが、まだ 100% 確実ではありません) は、このインスタンスの静的マップを共有します。これで、edit() を呼び出すたびに、新しい EditorImpl インスタンスが取得されます。質問で言及している「同期(this)」とは、手元の EditorImpl のインスタンスを指します。これはあまり機能しません。EditorImpl の内部マップへのアクセスを同期するだけです。ただし、(異なる) エディターは、この (SharedPreferencesImpl) インスタンスを変更しようとすると、(共通の) SharedPreferencesImplインスタンスで同期します。だからSharedPreferencesImplcommit()たとえば、同期がオンにcommitToMemory()なっている場所で呼び出されます。ただし、ディスクへの書き込みはランダムな順序でキューに入れられることに注意してください ( enqueueDiskWriteSoの javadoc を参照し、メモリへの書き込みとディスクへの書き込みのエンキューの間にロックが保持されないことに注意してください)。したがって、変更の順序に依存せず、アトミックにチェックして設定値を設定することに依存しない限り、設定を安全に変更する必要があります(独自の同期が必要です) NB引用したコードは2.3.1_r1用です-うまくいけば、まだ有効です SharedPreferencesImpl.thiscommit

于 2013-05-03T21:28:43.633 に答える