--
Stockage Android et processus en Background
! (data:image/jpeg;base64...)
CHAPITRE
N 4
1. Les options de Stockage Android
Android pr sente diff rents options pour la persistance des donn es. La solution choisie d pend des besoins sp cifiques de lapplication : donn es priv es ou partag es, lespace de stockage n cessaire pour ces donn es.
Les options de stockages sont les suivantes :
- Shared Preferences : cette technique stocke les donn es de lapplication sous forme cl /valeur.
- Stockage interne : les donn es stock es dans la m moire du t l phone en utilisant les fichiers I/O.
- SQLite Databases : stocke les donn es dans une base locale SQLIite.
- Base de donn es externe : On utilise les web services pour se connecter aux donn es stock s sur un serveur de BD externe.
- ContentProviders pour partager les donn es entre les applications.
1. Les fichiers I/O
Il sagit de lire et crire dans un fichier comme en java. Tous les appareils Android disposent de deux zones de stockage de fichiers: le stockage interne et le stockage externe .
| | |
| --- | --- |
| Stockage interne | Stockage externe |
| C'est toujours disponible. Les fichiers enregistr s ici sont accessibles uniquement par votre application. Lorsque l'utilisateur d sinstalle votre application, le syst me supprime tous les fichiers de votre application du stockage interne. Le stockage interne est le meilleur lorsque vous voulez tre s r que ni l'utilisateur ni les autres applications ne peuvent acc der vos fichiers. | Il n'est pas toujours disponible, car l'utilisateur peut le retirer du p riph rique. Lorsque l'utilisateur d sinstalle votre application, le syst me supprime les fichiers de votre application uniquement si vous les enregistrez dans le r pertoire de getExternalFilesDir (). * Le stockage externe est le meilleur emplacement pour les fichiers ne n cessitant pas de restrictions d'acc s et pour les fichiers partag s avec d'autres applications. |
- Permissions
Pour crire sur le stockage externe, vous devez demander l'autorisation WRITE\_EXTERNAL\_STORAGE dans votre fichier manifeste
<manifest ...>
<uses-permission android:name="android.permission.WRITE\_EXTERNAL\_STORAGE" />
...
</manifest>
Prochainement dans les releases futurs, il faut avoir la permission de lire, il faut donc ajouter
<manifest ...>
<uses-permission android:name="android.permission.READ\_EXTERNAL\_STORAGE" />
...
</manifest>
1. Enregistrer dans la m moire interne
String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE\_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
1. Lire de la m moire interne
public void LectureInterne(View v)
{ String FILENAME="monfichier.txt";
FileInputStream fis;
byte[] buffer=new byte[1024];
StringBuilder content =new StringBuilder();
try{
fis=openFileInput(FILENAME);
while(fis.read(buffer)!=-1)
{content.append(new String(buffer));}
}catch(FileNotFoundException e){e.printStackTrace();}
catch(IOException e){e.printStackTrace();}
AlertDialog.Builder alert=new AlertDialog.Builder(MainActivity.this)
.setMessage(content.toString())
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
Publicité
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alert.show();
1. Enregister dans la m moire externe
final String storageState= Environment.getExternalStorageState();
if(storageState.equals(Environment.MEDIA\_MOUNTED))
{//on peut lire et crire
File outFile=getExternalFilesDir(null);
String Filename="/monfichier.txt";
String str="exemple de stockage externe";
try{
BufferedWriter bw = new BufferedWriter(new FileWriter(outFile+Filename));
bw.write(str);
bw.close();
}
catch(FileNotFoundException e){e.printStackTrace();}
catch(IOException e){e.printStackTrace();}
}
- il est n cessaire de v rifier la disponibilit du stockage externe avant deffectuer nimporte quelle requ te en utilisant la m thode getExternalStorageState.
Les diff rents tats possibles :
- MEDIA\_BAD\_REMOVAL : le stockage est d branch avant d tre d mont .
- MEDIA\_CHACKING : le stockage est en cours de v rification.
- MEDIA\_MOUNTED : le stockage est disponible en lecture/ criture
- MEDIA\_MOUNTED\_READ\_ONLY : le stockage est disponible en lecture seule
- MEDIA\_NOFS : le stockage est disponible mais le formatage nest pas pris en charge.
- MEDIA\_REMOVED : le stockage nest pas pr sent.
- MEDIA\_SHARED : le stockage est utilis en USB (connect au PC).
- MEDIA\_UNMOUNTABLE : le stockage est pr sent mais ne peut pas tre mont .
- MEDIA\_UNMOUNTED : le stockage est pr sent mais nest pas mont .
1. Lecture dun fichier externe
// acc der au r pertoire par d faut du support externe
File outFile = Environment.getExternalStorageDirectory();
// Acc s au fichier
File file = new File(outFile + "/monfichier.txt");
// Tester si le fichier d sir existe, sinon, un Toast affiche un message derreur
if (!file.exists()) {
Toast.makeText(this, "Fichier nexiste pas dans la carte SD", 1000).show();
}else{ // Si le fichier existe
try {
// Cr er un BufferedReader pour parcourir le fichier en lecture
BufferedReader br = new BufferedReader(new FileReader(file));
// Stocker le contenu du fichier dans un buffer
String line;
StringBuffer buffer = new StringBuffer();
while ((line = br.readLine()) != null) {
buffer.append(line);
}
// Fermer le fichier
br.close();
} catch(FileNotFoundException e){e.printStackTrace();}
catch(IOException e){e.printStackTrace();}
}
1. Shared Preferences
Si vous avez une collection relativement petite de valeurs-cl s que vous souhaitez enregistrer, utilisez les API SharedPreferences. Un objet SharedPreferences pointe vers un fichier contenant des paires cl -valeur et fournit des m thodes simples pour les lire et les crire. Chaque fichier SharedPreferences est g r par le framework et peut tre priv ou partag .
1. Instancier Shared Preferences
Vous pouvez cr er un nouveau fichier de pr f rences partag es ou acc der un fichier existant en appelant l'une des deux m thodes suivantes:
- getSharedPreferences () - Utilisez-le si vous avez besoin de plusieurs fichiers de pr f rences partag es identifi s par leur nom, que vous sp cifiez avec le premier param tre. Vous pouvez l'appeler depuis n'importe quel contexte de votre application.
- getPreferences () - Utilisez-le partir d'une activit si vous devez utiliser un seul fichier de pr f rences partag es pour l'activit . Comme ce fichier r cup re un fichier de pr f rences partag es par d faut appartenant l'activit , il n'est pas n cessaire de fournir un nom.
Publicité
Par exemple, le code suivant est ex cut l'int rieur d'un fragment. Il acc de au fichier de pr f rences partag es identifi par la cha ne de ressources R.string.preference\_file\_key et l'ouvre en mode priv afin que le fichier soit accessible uniquement par votre application.
Contexte contexte = getActivity ();
SharedPreferences sharedPref = context.getSharedPreferences (
getString (R.string.preference\_file\_key), Context.MODE\_PRIVATE);
Lorsque vous nommez vos fichiers de pr f rences partag es, vous devez utiliser un nom qui est uniquement identifiable votre application, par exemple "com.example.myapp.PREFERENCE\_FILE\_KEY"
Alternativement, si vous avez besoin d'un seul fichier de pr f rences partag es pour votre activit , vous pouvez utiliser la m thode getPreferences ():
SharedPreferences sharedPref = getActivity (). GetPreferences(Context.MODE\_PRIVATE);
N.B: si vous cr ez un fichier de pr f rences partag es avec MODE\_WORLD\_READABLE ou MODE\_WORLD\_WRITEABLE, toutes les autres applications connaissant l'identificateur de fichier peuvent acc der vos donn es.
1. Ecrire dans shared preferences
Pour crire dans un fichier de pr f rences partag , cr ez un SharedPreferences.Editor en appelant edit () sur vos pr f rences SharedPreferences.
Passez les cl s et les valeurs que vous voulez crire avec des m thodes telles que
putInt () et putString (). Appelez ensuite commit() pour enregistrer les modifications. Par exemple:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE\_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.saved\_high\_score), newHighScore);
editor.commit();
1. Lire partir de shared preferences
Pour extraire les valeurs d'un fichier de pr f rences partag es, appelez des m thodes telles que getInt () et getString (), fournissant la cl de la valeur que vous voulez et ventuellement une valeur par d faut retourner si la cl n'est pas pr sente. Par exemple:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE\_PRIVATE);
int defaultValue = getResources().getInteger(R.string.saved\_high\_score\_default);
long highScore = sharedPref.getInt(getString(R.string.saved\_high\_score), defaultValue);
1. Sauvagarder l tat dune actvit
SharedPreferences est utilis pour sauvegarder l tat dune activit .
Par exemple : sauvegarder les champs dun formulaire lors dune interruption caus e par un appel t l phonique. Lorsque lutilisateur reprend lactivit , on charge de nouveau le formulaire.
Il faut reimpl menter onPause() pour sauvegarder les pr f rences et onResume() pour retrouver les pr f rences.
1. Processus en Background
Par d faut, le code d'application s'ex cute dans le thread principal. Chaque d claration est donc ex cut e dans l'ordre. Si vous effectuez une op ration de longue dur e, l'application se bloque jusqu' ce que l'op ration correspondante soit termin e.
Pour offrir une bonne exp rience utilisateur, toutes les op rations potentiellement lentes d'une application Android doivent tre ex cut es de mani re asynchrone. Cela peut tre archiv via des constructions concurrentielles du langage Java ou du framework Android. Les op rations potentiellement lentes sont par exemple l'acc s au r seau, aux fichiers et aux bases de donn es et les calculs complexes.
Le background processing en Android se fait travers :
- Les threads
- Les services
- Les fragments en background
1. Les threads
On a 2 types de threads :
- UI thread : main thread. Cest le thread de lactivit cr e lors de la cr ation de lactivit .
- Worker thread : chaque thread lanc par UI thread pour assurer une t che en background.
Pour cr er des workers thread, on utilise java thread ou la solution android simplifi e : AsyncTask.
AsyncTask : cest une classe ayant les propri t s qui suivent :
- Permet le traitement asynchrone dans votre application
- Cr e un worker thread et envoie les r sultats au UI thread
- Id al pour les t ches courtes en background
Exemple : Se connecter internet pour collecter des donn es n cessite de lancer un AsyncTask
AsyncTask doit tre sous-classifi pour tre utilis . La sous-classe remplacera au moins une m thode (doInBackground (Params ...)), et remplacera le plus souvent une seconde (onPostExecute (Result)).
Voici un exemple: telecharger des fichiers en background
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long>
- URL:Param tres envoy s au thread pour lex cution
- Long : r sultat final
- Integer : pourcentage de progression du thread durant lex cution
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls );
publishProgress((int) ((i / (float) count) \* 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
Publicité
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes"); } }
une fois cr e, lAsyncTask est execute simplement:
new DownloadFilesTask().execute(url1, url2, url3);
1. Les services
Un service est un composant d'application qui peut effectuer des op rations de longue dur e en arri re-plan et ne fournit pas d'interface utilisateur. Un autre composant d'application peut d marrer un service et il continue s'ex cuter en arri re-plan m me si l'utilisateur passe une autre application. En outre, un composant peut se lier un service pour interagir avec lui et m me effectuer une communication interprocessus (IPC). Par exemple, un service peut g rer des transactions r seau, jouer de la musique, effectuer des E / S de fichiers ou interagir avec un fournisseur de contenu, tous en arri re-plan.
Un service h rite de deux classes : Service te IntentService
- Exemple de lancement dun service :
Le lancement dune application musicale se fait comme suit :
- D marrage de lactivit qui permet de faire le choix de chanson
- Lutilisateur lance la musique
- Le service diffuse cette musique
- Lutilisateur peut quitter lapplication en fermant lactivit
- La musique continue tre diffus e
- Etapes de communication avec un service :
Pour communiquer avec un service il faut :
- Sy connecter (il se lance si il tait arret )
- Utiliser linterface que pr senter ce service, exemple : Play(), Pause(), next() ...
- Un service sex cute dans un Thread et donc ne bloque pas le reste du terminal quand il tourne en fond.
- Impl mentation dun service
Le service se d clare dans le Manifest dans le tag application:
<service android:name=".AndroService"/>
La structure d'une classe de service ressemble une activit . Pour r aliser un service, on h rite de la classe Service et on impl mente les m thodes de cr ation/d marrage/arr t du service. La nouvelle m thode qu'il faut impl menter est onBind qui permet aux IPC (InterProcessCommunication) de faire des appels des m thodes distantes.
public class AndroService extends Service {
public void onCreate() {
// Cr ation du service
}
public void onDestroy() {
// Destruction du service
}
@deprecated // utile pour les versions ant rieures d'Android 2.0
public void onStart(Intent intent, int startId) {
// D marrage du service
}
public int onStartCommand(Intent intent, int flags, int startId) {
// D marrage du service
return START\_STICKY;
}
public IBinder onBind(Intent arg0) {
return null;
}}
- + D marrer / Arr ter un service
Les Intents fournissent un moyen de d marrer/arr ter un service en utilisant le nom de la classe du service ou un identifiant d'action:
startService(new Intent(this, AndroService.class));
stopService(new Intent(this, AndroService.class));
startService(new Intent("iset.sem.manageServiceAction"));
Ces m thodes sont invoquer dans l'activit de l'application d velopp e. On dit alors que le service est local l'application: il va m me s'ex cuter dans le thread de l'application. Un bouton de d marrage d'un service local est simple coder:
Button b = (Button) findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent startService = new Intent("iset.dsi.manageServiceAction");
startService(startService);}});
1. IntentService
Un autre design pattern a t simplifi dans Android: l'ex cution dans un processus isol de jobs provenant d'une autre partie de l'application. Les jobs sont provisionn s au travers d'un Intent et l'IntentService ex cute la t che dans la m thode onHandleIntent(), ind pendamment de l'UI thread.
public class MonServiceLourd extends IntentService {
{public MonServiceLourd() {
Publicité
super("MonServiceLourd");}
@Override
protected void onHandleIntent(Intent intent) {
... // T che longue, par exemple un t l chargement}}
Le b n fice, qui n'est pas visible ici, est que les Intent sont mis dans une file d'attente et trait s les uns apr s les autres, vitant une surcharge du syst me. Chaque Intent est trait par onHandleIntent() et le service s'arr te tout seul quand il n'y a plus rien traiter.
1. Se connecter Internet via Android
La connexion se fait travers un AsynchTask comme suit :
class connexiontask extends AsyncTask<String,Void,String>
{
@Override
protected String doInBackground(String... strings) {
String res = null;
res= connectweb();
return res;
}
@Override
protected void onPostExecute(String res) {
if(res!=null)
txt.setText(res);
super.onPostExecute(res);
}
}
public String connectweb() {
String responseText=null;
URL url= null;
try {
url = new URL("http://api.geonames.org/postalCodeLookupJSON?postalcode=6600&country=AT&username=demo");
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("Get");
httpURLConnection.connect();
int httpResponseCode = httpURLConnection.getResponseCode();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
String inputLine;
StringBuffer stringBuffer=new StringBuffer();
while((inputLine=bufferedReader.readLine())!=null)
{stringBuffer.append(inputLine);
}
bufferedReader.close();
responseText=stringBuffer.toString();
} catch (IOException e) {
e.printStackTrace();
}
return responseText;
}
