
Si vous développez des appli Android, il vous est sûrement déjà arrivé de devoir remplir passer des données d'une activité à une autre, et de vous apercevoir que lorsque vous tourniez votre téléphone les données du bundle étaient perdues.
Cela est une problématique classique du cycle de vie d'une activité sur Android. En effet, lors d'une rotation, votre activité est détruite, et elle se rappelle elle-même en quelque sorte. De ce faite, toutes les données qui avaient été stockées dans les variables automatiques sont initialisées à nouveau. Une façon de conserver ces données serait de passer les variables en statiques, et c'est une erreur que je considérerais de débutant, que j'ai faite à mes débuts. Sur le principe cela fonctionne, mais le code n'est pas propre.
Le meilleure pratique est, je pense, de considérer la surcharge de la méthode
onSaveInstanceState(Bundle icicle) de la classe Activity. Prenons une activité classique:
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class testActivity extends Activity
{
String test;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
test = getIntent().getExtras().getString("test", "test perdu");
Log.d("test bundle", test);
}
}
Si vous avez lancé l'activité depuis une autre activité de cette façon:
Intent i = new Intent(this, testActivity.class);
i.putExtra("test", "test ok");
startActivity(i);
Votre logcat va afficher
test ok.
Si vous faites une rotation de l'écran, votre logcat affiche
test perdu. C'est là qu'intervient
onSaveInstanceState(Bundle icicle). Celui-ci va être appelé avant la destruction de l'activité. Nous allons donc l'implémenter ainsi:
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class testActivity extends Activity
{
String test;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
test = getIntent().getExtras().getString("test");
if (test == null) savedInstanceState.getString("test", "test non défini");
Log.d("test bundle", test);
}
@Override
protected void onSaveInstanceState(Bundle outState)
{
outState.putString("test", test);
super.onSaveInstanceState(outState);
}
}
Comme on peut le voir ici, on place dans le
bundle outState toutes les données que l'on veut sauvegarder. Nous avons légèrement modifier le traitement de la méthode
onCreate(Bundle savedInstanceState) pour récupérer ces données que nous avons stockée dans outState. Donc on récupère, par exemple, les extras qui auraient du être passés par l'activité précédente. Si ces extras ont disparu à la rotation, on regarde si l'on ne peut pas les récupérer dans le
savedInstanceState, qui est une copie du bundle
outState précédent.
Bien sûr, cela ne fonctionne pas qu'avec les String, toutes les données stockables dans un bundle peuvent être sauvegardées dans outState de
onSaveInstance et récupérée dans le savedInstance de
onCreate après la rotation.
Vous pouvez désormais vous passer de ces vilaines variables statiques que l'on ne saurait voir et faire des rotations d'activité en conservant vos données :)