2012-12-29 12 views
9

Ad esempio, se vengono aggiunte o eliminate alcune voci di preferenze, in che modo Android gestisce i dati delle preferenze esistenti quando l'app viene aggiornata con la nuova struttura delle preferenze?Cosa succede ai dati esistenti delle preferenze degli utenti Android quando la struttura delle preferenze cambia in una nuova versione?

Mi dispiace per questa domanda rudimentale, ma la mia diligente ricerca e lettura non ha potuto trovare la risposta.

+0

Puoi estrarre il file XML di prefs da DDMS e cercare te stesso, se lo desideri – mango

risposta

6

Le preferenze condivise sono memorizzate nel file xml nella cartella data/data/your.application.package/shared_prefs/. Il file si chiama your.application.package_preferences.xml;

Quando si recuperano le preferenze condivise, si chiama il metodo Context.getSharedPreferences. Crea l'oggetto SharedReferences e invoca il metodo SharedReferences.startLoadFromDisk.

Se si apre questo metodo, si vedrà che il file xml con le preferenze (mFile) viene analizzato e le preferenze vengono caricate nell'archivio di memoria (map).

BufferedInputStream str = new BufferedInputStream(new FileInputStream(mFile), 16*1024); 
map = XmlUtils.readMapXml(str); 

Da allora leggerai sempre le tue preferenze dalla memoria. Più esattamente dalla variabile private Map<String, Object> mMap. Anche l'applicazione può chiamare il metodo startReloadIfChangedUnexpectedly e se il file sottostante è stato modificato, verrà analizzato e verrà creata una nuova HashMap.

Quanto alla tua domanda, vi sono le seguenti casi:

  1. è stato aggiunto un elemento preferenza in una nuova versione. Quindi verrà restituito il valore predefinito specificato come secondo parametro. Nota: l'attributo android: defaultValue non viene utilizzato, quindi fai attenzione.

    String v = (String)mMap.get(key); // not found => v = null

    return v != null ? v : defValue; // return defValue

  2. è stato rimosso un elemento preferenza in una nuova versione. Il file xml e l'oggetto map conterranno alcuni dati ridondanti, ma verranno riparati quando l'utente salva le preferenze la volta successiva.

  3. Hai cambiato la chiave di una voce di preferenza in un tasto che non è stato utilizzato. Quindi verrà restituito il valore predefinito. Lo stesso risultato di p.1.

  4. È rimosso un elemento preferenza (con la chiave pref1_key, per esempio) e cambiato la chiave di un altro elemento in modo che si riferisce al primo elemento (da pref2_key a pref1_key). Quindi il secondo elemento preferenza avrà il valore del primo elemento.

  5. È stato modificato un tipo di elemento preferenza (da booleano ad int, ad esempio). Quindi genererà CastException a causa di questo codice simile: (Integer)mMap.get(key);. Ma è possibile modificare, ad esempio, EditTextPreference in ListPreference, poiché entrambi hanno il tipo String.

Forse ci sono alcuni più casi di test, ma finora ho fatto solo 5.

Anche qui è l'esempio dei file delle preferenze con ListPreference, EditTextPreference e CheckBoxPreference:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?> 
<map> 
    <string name="pref_theme_key">THEME_LIGHT</string> 
    <string name="pref_homepage_key">test</string> 
    <boolean name="pref_display_name_key" value="true" /> 
</map> 
+0

Grazie mille per la risposta dettagliata. I tuoi casi elencati erano esattamente ciò che avevo in mente. Ho pensato che cambiare la struttura delle preferenze fosse uno scenario abbastanza comune durante lo sviluppo di app, ma non ho trovato nulla che lo riguardasse nel documento di Android. Forse, non stavo guardando il documento giusto. – Hong

+2

@Hong A volte non ci sono informazioni nella documentazione ufficiale, è per questo che utilizzo il sito web di grepcode ed esamino personalmente il codice sorgente. – vorrtex

2

in che modo Android gestisce i dati delle preferenze esistenti quando l'app viene aggiornata con la nuova struttura delle preferenze?

Non è chiaro cosa intendi per "struttura delle preferenze".

Si può pensare a un SharedPreferences come un persistente HashMap. Memorizzi vari valori sotto vari tasti e puoi recuperarli in un secondo momento. Android non ha a priori conoscenza delle chiavi o dei tipi di valori che verranno memorizzati sotto quelle chiavi, fino a quando non memorizzi qualcosa.

La mia ipotesi è che per "struttura delle preferenze" si intende "definizioni schermo preferenza in XML". In tal caso:

  • se si aggiungono nuove preferenze, Android gestirà quelli normalmente, proprio come se le preferenze è stato intorno tutto il tempo, ma l'utente non aveva mai messo le preferenze prima

  • se si rimuove preferenze che avevi usato prima, i vecchi dati rimangono, a meno che tu non abbia scelto di sbarazzartene, dato che Android non ha modo di sapere che non userai mai più quei dati

  • se si ridisegna una preferenza (es. , sostituire keyA con key1 per quello che logicamente è lo stesso preferenza), Android tratterà key1 come totalmente nuova preferenza, e quindi sarà necessario mettere intelligenza nel codice da qualche parte per aggiornare i dati SharedPreferences per riflettere il cambiamento chiave, se lo si vuole

Non c'è SharedPreferencesOpenHelper equivalente a SQLiteOpenHelper per gestire le "versioni dello schema" delle preferenze e facilitare la migrazione dei dati. Siete invitati a creare un tale sistema, se lo desiderate, se ritenete che vi aiuterà a gestire una "struttura delle preferenze" che cambia frequentemente.

Problemi correlati