質問

を見ています SharedPreferencesドキュメント それは言う:

「注:現在、このクラスは複数のプロセスにわたる使用をサポートしていません。これは後で追加されます。」

したがって、それ自体では、糸が安全であるようには見えません。ただし、commit()とapply()に関してどのような保証が行われますか?

例えば:

synchronized(uniqueIdLock){
   uniqueId = sharedPreferences.getInt("UNIQUE_INCREMENTING_ID", 0);
   uniqueId++;
   sharedPreferences.edit().putInt("UNIQUE_INCREMENTING_ID", uniqueId).commit();
}

この場合、UniqueIDが常にユニークであったことは保証されますか?

そうでない場合、持続するアプリケーションの一意のIDを追跡するより良い方法はありますか?

役に立ちましたか?

解決

プロセスとスレッドは異なります。 AndroidでのSharedPreferencesの実装はスレッドセーフですが、プロセスセーフではありません。通常、アプリはすべて同じプロセスですべて実行されますが、AndroidManifest.xmlで構成することができます。たとえば、サービスはアクティビティよりも別のプロセスで実行されます。

スレッドの安全性を確認するには、AOSPのContextImpl.javaの共有PreferenceImplを参照してください。注意してください。

private static final class SharedPreferencesImpl implements SharedPreferences {
...
    public String getString(String key, String defValue) {
        synchronized (this) {
            String v = (String)mMap.get(key);
            return v != null ? v : defValue;
        }
   }
...
    public final class EditorImpl implements Editor {
        public Editor putString(String key, String value) {
            synchronized (this) {
                mModified.put(key, value);
                return this;
            }
        }
    ...
    }
}

ただし、一意のIDの場合、GetとPutの間に変更したくないため、まだ同期したいと思われます。

他のヒント

私は同じことを疑問に思っていました - そして出会いました このスレッド それは彼らが糸が安全ではないと言っています:

Context.GetSharedPreferences()およびEditor.Commit()の実装は、同じモニターで同期しません。


それ以来、チェックするAndroid 14コードを見てきましたが、それは非常に関与しています。具体的には SharedPreferencesImpl ディスクへの読み取りと書き込みの際に、異なるロックを使用しているようです:

  • enqueueDiskWrite() ロックします mWritingToDiskLock
  • startLoadFromDisk() ロックします this, 、およびロックオンスレッドを起動します SharedPreferencesImpl.this

このコードは本当に安全であることに納得できません。

SharedPreferencesがSamsungの携帯電話で機能していないことに注意する必要があります。 Androidの問題.

あなたが見つけることができる簡単なデータベース設定ストレージを実装しました github.

乾杯、

私はそれがそれをするだろうと思います。

同期セクション内の睡眠を使用してテストし、異なるスレッドから呼び出すことができます

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top