Вопрос

Глядя на SharedPreferences Docs это говорит:

«Примечание: в настоящее время этот класс не поддерживает использование в нескольких процессах. Это будет добавлено позже».

Таким образом, само по себе это не кажется безопасным. Тем не менее, какие гарантии сделаны в отношении Commit () и Apply ()?

Например:

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

Будет ли гарантировано, что уникальный ID всегда был уникальным в этом случае?

Если нет, есть ли лучший способ отслеживать уникальный идентификатор для приложения, которое сохраняется?

Это было полезно?

Решение

Процессы и потоки разные. Реализация SharedPreferences в Android безопасна, но не безопасна для процесса. Обычно ваше приложение будет запускать все в одном и том же процессе, но вы можете настроить его в AndroidManifest.xml, скажем, служба работает в отдельном процессе, чем, скажем, на действие.

Чтобы проверить ниточную безопасность, см. ContextImpl.java's SharedPreferenceImpl из AOSP. Обратите внимание, что есть синхронизированный, где бы вы ни ожидали.

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;
            }
        }
    ...
    }
}

Однако для вашего случая уникального идентификатора кажется, что вы все равно хотите синхронизировать, поскольку вы не хотите, чтобы он изменился между Get и PUT.

Другие советы

Мне было интересно то же самое - и наткнулся эта ветка Это говорит о том, что они не безопасны по тему:

Реализации Context.getSharedPreferences () и editor.commit () не синхронизируются на том же мониторе.


С тех пор я посмотрел на код Android 14 для проверки, и он вполне вовлечен. Конкретно SharedPreferencesImpl кажется, использует разные замки при чтении и написании на диск:

  • enqueueDiskWrite() замки на mWritingToDiskLock
  • startLoadFromDisk() замки на this, и запускает нить, блокирующую SharedPreferencesImpl.this

Я не убежден, что этот код действительно безопасен.

Вы должны знать, что SharedPreferences не работает над мобильными телефонами Samsung, посмотрите на Проблема с андроидом.

Я реализовал простое хранение предпочтений базы данных, которое вы можете найти на GitHub.

Ваше здоровье,

Я думаю, что это сделает это.

Вы можете проверить его, используя сон внутри синхронизированного раздела и вызовать из разных потоков

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top