La persistance des données
Introduction
Ce chapitre a pour but de présenter la persistance des données sous Android.
Les données persistantes d’une application sont les données sauvegardées avant la fermeture de l’application de telle sorte qu’elles puissent être restaurées ultérieurement.
Android propose plusieurs mécanismes permettant de gérer la persistance de données, selon la nature de ces données. Nous découvrirons les fichiers de préférences, les fichiers standards et les bases de données.
Nous terminerons par les fournisseurs de contenus qui, au-delà de la persistance des données, proposent un mécanisme de partage de données entre les applications.
Fichiers de préférences
Android fournit un framework simple pour sauvegarder et restaurer des données de types primitifs. Ces données sont sauvegardées dans des fichiers au format XML sous la forme d’associations clés-valeurs. Ces fichiers sont appelés fichiers de préférences.
Nous allons étudier dans un premier temps comment cibler un fichier de préférences, puis comment le lire et y écrire des données. Nous terminerons par décrire comment supprimer toutes ou partie des données de ces fichiers.
Le système Android permet d’afficher et de sauvegarder les préférences générales de l’utilisateur. Toute application peut adopter la même fonctionnalité et le même affichage. La hiérarchie des préférences proposées peut être réalisée directement dans un fichier XML. L’implémentation d’un tel écran de préférences est réalisée en dérivant de la classe PreferenceActivity. Depuis Android 3.0 (API 11), cette classe fonctionne de concert avec les fragments de type PreferenceFragment afin de pouvoir, entre autres, afficher côte à côte les titres des sections et les préférences qu’elles proposent.
1. Cibler le fichier
Par défaut, un fichier de préférences est associé à l’activité qui le crée. Ce fichier porte automatiquement le nom qualifié entier de l’activité concernée, par exemple fr.mondomaine.android.monappli.prefsFic1.xml.
La création et la gestion du fichier de préférences sont réalisées au travers d’un objet de type SharedPreferences retourné par la méthode getPreferences de la classe Activity.
Syntaxe
public SharedPreferences...
Fichiers
Comme nous venons de le voir dans la section précédente, les fichiers de préférences sont la solution idéale pour sauvegarder des valeurs de types primitifs de manière simple. Mais si l’on veut stocker des données plus complexes ou des données brutes sans reformatage du fichier au format XML, comme par exemple la sauvegarde d’une image au format PNG, cette solution n’est plus du tout envisageable.
Il faut alors pouvoir créer, écrire et lire directement des fichiers.
Android permet d’enregistrer des fichiers sur le stockage interne de l’appareil ou sur un stockage externe comme par exemple une carte SD. Il fournit également les API pour enregistrer des fichiers temporaires ou fichiers de cache dans des emplacements bien définis.
Nous allons donc découvrir dans un premier temps la gestion des fichiers sur le stockage interne, puis dans un second temps sur le stockage externe. Enfin, nous terminerons par la gestion des fichiers temporaires.
1. Stockage interne
Par défaut, les fichiers sont enregistrés sur le stockage interne de l’appareil. L’accès à ces fichiers est restreint à l’application. Ni l’utilisateur ni les autres applications ne peuvent y accéder.
Nous allons voir comment créer un fichier sur le stockage interne, comment le lire et enfin comment le supprimer.
a. Écriture
La création d’un fichier se fait en invoquant la méthode openFileOutput de la classe Context. Cette méthode attend deux paramètres : le nom du fichier sans arborescence et le mode d’accès à assigner à ce fichier. La méthode retourne un flux de type FileOutputStream.
Syntaxe
public abstract FileOutputStream openFileOutput (String name,
int mode)
Exemple
FileOutputStream flux = openFileOutput("nomFichier.png",
Context.MODE_PRIVATE);
Le flux retourné permet d’écrire les données brutes dans le fichier en utilisant les différentes méthodes write.
Syntaxe
public void write (byte[] buffer)
public void write (int oneByte)
public void write (byte[] buffer, int offset, int count)
Exemple
flux.write(contenu.getBytes());
Il reste à fermer le flux afin d’écrire complètement le fichier sur le support...
Bases de données SQLite
Une application peut avoir besoin d’une base de données pour stocker et effectuer des requêtes sur ses données. Android permet de créer des bases de données au format SQLite.
Une application peut créer plusieurs bases de données. Ces bases sont privées à l’application ; elle seule y a accès.
Dans cette section, nous allons découvrir comment créer une base de données et y ajouter une table. Puis nous verrons comment exécuter des requêtes. Enfin, nous terminerons par la modification d’une base de données existante.
1. Création d’une base de données
Android fournit la classe abstraite SQLiteOpenHelper permettant de gérer la création et la mise à jour des bases de données.
Cette classe étant abstraite, il faut créer une classe fille qui en hérite. Cette classe fille doit appeler le constructeur parent et lui passer le nom et la version de la base de données en paramètres. Le numéro de version est utilisé lors de la mise à jour de la base dans une nouvelle version comme nous le verrons plus loin.
En héritant de la classe parente SQLiteOpenHelper, la classe fille doit surcharger, entre autres, la méthode onCreate. Celle-ci permet de spécifier les requêtes de création des tables de la base.
Syntaxe
public abstract void onCreate (SQLiteDatabase db)
Exemple
public class BDDAssistant extends SQLiteOpenHelper {
private static final int VERSION_BDD = 1;
private static final String NOM_BDD = "maBDD";
public BDDAssistant(Context context) {
super(context, NOM_BDD, null, VERSION_BDD);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE maTable ( _id INTEGER PRIMARY KEY
AUTOINCREMENT, nom TEXT );");
}
}
La classe SQLiteOpenHelper fournit la méthode getWritableDatabase pour créer et ouvrir la base de données. Elle retourne un objet de type SQLiteDatabase accessible en écriture permettant de modifier la base de données.
Syntaxe
public synchronized SQLiteDatabase getWritableDatabase...
Fournisseur de contenus
Les fournisseurs de contenus permettent de partager publiquement des données entre toutes les applications. C’est le cas par exemple des données concernant les contacts personnels qui peuvent être partagées entre toutes les applications. Chaque application peut, si elle en a obtenu les droits, lire, ajouter et modifier les contacts personnels.
Il existe par défaut plusieurs fournisseurs de contenus pour les données audio, vidéo, les images, les contacts personnels… Ils peuvent être utilisés tels quels pour y stocker de nouveaux enregistrements. Cela permet de ne pas avoir à en créer de nouveaux.
Nous allons décrire l’interface commune aux fournisseurs de contenus, puis voir comment effectuer des requêtes et des modifications sur ces fournisseurs de contenus. Enfin, nous verrons comment supprimer des enregistrements des fournisseurs de contenus.
1. Interface et URI
Tous les fournisseurs de contenus exposent la même interface. En interne cependant, chacun est libre de sauvegarder ses données en utilisant la ou les solutions de stockage qu’il souhaite.
Quel que soit le mode de stockage interne, les fournisseurs de contenus retournent leurs données sous forme de tables de base de données. Chaque ligne est un enregistrement et chaque colonne une valeur correspondant au champ concerné.
Chaque enregistrement possède un champ numérique _ID qui identifie de façon unique l’enregistrement dans la table.
Chaque fournisseur de contenus fournit une URI unique qui correspond à une table de ses données. Il y aura donc autant d’URI que de tables de données.
Syntaxe de l’URI
content://fr.domaine.nomProvider
content://fr.domaine.nomProvider/id
content://fr.domaine.nomProvider/sous-chemins
content://fr.domaine.nomProvider/sous-chemins/id
Partie |
Description |
content:// |
Indique que les données sont contrôlées... |
Sauvegarde dans les nuages
Depuis la version 2.2 (API 8), Android propose la sauvegarde des données persistantes de l’application dans un nuage, c’est-à-dire en ligne, sur un serveur. C’est un service complémentaire à celui de la sauvegarde des données en local.
Lorsque l’utilisateur réinitialise l’appareil Android, lorsqu’il change d’appareil ou utilise un nouvel appareil supplémentaire, comme une tablette en complément d’un smartphone, il peut souhaiter (ré)installer une même application. Le fait de devoir reconfigurer l’application et y réinsérer certaines données de façon manuelle sont des tâches qui peuvent paraître rébarbatives pour l’utilisateur.
C’est là que la sauvegarde en ligne entre en jeu. Celle-ci permet d’éviter ces tâches de configuration longues et fastidieuses. Les données préalablement sauvegardées en ligne peuvent être téléchargées et insérées lors d’une nouvelle installation de l’application. L’utilisateur retrouvera alors automatiquement l’application et les données l’accompagnant sans action de sa part.
Les données sont associées au compte utilisateur Google principal configuré sur l’appareil. L’utilisateur devra donc avoir configuré le même compte principal sur ses différents appareils pour profiter pleinement de cette fonctionnalité.
À noter que bien que cette fonctionnalité soit présente dans la majorité des appareils Android, certains ne la proposent pas. L’utilisateur peut également désactiver cette fonctionnalité dans les paramètres généraux du système. Dans de tels cas, l’application fonctionnera normalement ; les données persistantes ne seront simplement pas sauvegardées ni restaurées. Charge à l’utilisateur de les réinsérer manuellement.
L’application n’envoie pas elle-même ses données persistantes sur le serveur. Elle communique avec le Gestionnaire de sauvegarde sur le système Android. Celui-ci se charge de préparer les données à envoyer, de communiquer avec le serveur...
Prise en charge du JSON
La fin de ce chapitre sur les données est consacrée, bien que cela ne soit pas à proprement parler un support pour la persistance des données, à la prise en charge du format JSON par la plateforme Android.
1. Présentation du format JSON
Le format JSON (pour JavaScript Object Notation) est en effet un format de données qui tend à se généraliser pour la transmission de données via le réseau : simple à mettre en œuvre, facilement interprétable, il a également pour avantage d’être peu verbeux - comparé au format XML, par exemple. La bibliothèque réseau Volley, présentée au chapitre Concurrence, sécurité et réseau, prend, par exemple, entièrement en charge ce format.
En JSON, les données sont écrites au format texte, sous la forme d’ensembles de listes de couple nom de la donnée/valeur de la donnée.
Les données peuvent être de plusieurs types différents : chaîne de caractères, nombre, booléen, objet, ou le type spécial null. Les tableaux de données sont également pris en charge.
Exemple
{"contacts" :
[
{
"id" : 1,
"nom" : "Martin",
"prenom" : "Pierre",
"telephone" : "0102030405",
"disponible" : true,
"email" : null
},
{
"id" : 2,
"nom" : "Michel",
"prenom" : "Dominique",
"telephone" : "0504050709",
"disponible" : true, ...