SharedPreferences et sécurité du fil
-
11-10-2019 - |
Question
En regardant le SharedPreferences docs il est dit:
"Note: actuellement cette classe ne Soutenir l'utilisation sur plusieurs processus. Ce point sera ajouté plus tard. "
Donc, en soi, il ne semble pas être thread-safe. Cependant, quel genre de garanties sont faites en ce qui concerne commit () et appliquer ()?
Par exemple:
synchronized(uniqueIdLock){
uniqueId = sharedPreferences.getInt("UNIQUE_INCREMENTING_ID", 0);
uniqueId++;
sharedPreferences.edit().putInt("UNIQUE_INCREMENTING_ID", uniqueId).commit();
}
Ne serait-il garantir que le uniqueId était toujours unique dans ce cas?
Dans le cas contraire, est-il une meilleure façon de garder une trace d'un identifiant unique pour une application qui persiste?
La solution
Processus et threads sont différents. La mise en œuvre de SharedPreferences dans Android est thread-safe, mais pas processus de sécurité. Normalement, votre application fonctionnera tout dans le même processus, mais il est possible pour vous de le configurer dans le AndroidManifest.xml ainsi, par exemple, le service fonctionne dans un processus séparé que, par exemple, l'activité.
Pour vérifier la sécurité thready, voir SharedPreferenceImpl de PSBA du ContextImpl.java. Remarque il y a un partout où vous synchronisés attendez qu'il y ait un.
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;
}
}
...
}
}
Cependant, pour votre cas de l'identifiant unique, il semble que vous souhaitez toujours voulez une synchronisation que vous ne voulez pas changer entre le get et la vente.
Autres conseils
Je me demandais la même chose - et suis tombé sur ce thread- qui dit qu'ils ne sont pas thread-safe:
Les mises en œuvre de Context.getSharedPreferences () et Editor.commit () Ne sont pas synchronisées sur le même moniteur.
J'ai depuis regardé le code Android 14 pour vérifier, et il est tout à fait impliqué. Plus précisément SharedPreferencesImpl
semble utiliser des serrures lors de la lecture et l'écriture sur le disque:
- serrures
enqueueDiskWrite()
surmWritingToDiskLock
- serrures
startLoadFromDisk()
surthis
, et lance un verrouillage de fil surSharedPreferencesImpl.this
Je ne suis pas convaincu que ce code est vraiment sûr.
Je pense que cela va le faire.
Vous pouvez le tester à l'aide de sommeil dans la section synchronisée et l'appeler à partir de fils différents