Voici une compilation des moyens les plus courants pour y parvenir :
- Envoyer des données à l'intérieur de l'intention
- Champs statiques
- HashMap of
WeakReferences
- Persister les objets (sqlite, partager les préférences, fichier, etc.)
TL; DR : il existe deux façons de partager des données: passer des données dans les extras de l'intention ou les enregistrer ailleurs. Si les données sont des primitives, des chaînes ou des objets définis par l'utilisateur: envoyez-les dans le cadre des extras d'intention (les objets définis par l'utilisateur doivent implémenter Parcelable
). Si vous passez des objets complexes, enregistrez une instance dans un singleton ailleurs et accédez-y à partir de l'activité lancée.
Quelques exemples de comment et pourquoi mettre en œuvre chaque approche:
Envoyer des données dans des intentions
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("some_key", value);
intent.putExtra("some_other_key", "a value");
startActivity(intent);
Sur la deuxième activité:
Bundle bundle = getIntent().getExtras();
int value = bundle.getInt("some_key");
String value2 = bundle.getString("some_other_key");
Utilisez cette méthode si vous transmettez des données primitives ou des chaînes . Vous pouvez également passer des objets qui implémentent Serializable
.
Bien que tentant, vous devriez réfléchir à deux fois avant de l'utiliser Serializable
: il est sujet aux erreurs et horriblement lent. Donc en général: éloignez-vousSerializable
si possible. Si vous souhaitez transmettre des objets définis par l'utilisateur complexes, jetez un œil à l' Parcelable
interface . Il est plus difficile à mettre en œuvre, mais il a des gains de vitesse considérables par rapport à Serializable
.
Partagez des données sans persister sur le disque
Il est possible de partager des données entre des activités en les enregistrant en mémoire étant donné que, dans la plupart des cas, les deux activités s'exécutent dans le même processus.
Remarque: parfois, lorsque l'utilisateur quitte votre activité (sans la quitter), Android peut décider de tuer votre application. Dans un tel scénario, j'ai rencontré des cas dans lesquels Android tente de lancer la dernière activité en utilisant l'intention fournie avant la mort de l'application. Dans ce cas, les données stockées dans un singleton (le vôtre ou Application
) disparaîtront et de mauvaises choses pourraient se produire. Pour éviter de tels cas, vous pouvez soit persister les objets sur le disque, soit vérifier les données avant de les utiliser pour vous assurer qu'elles sont valides.
Utiliser une classe singleton
Demandez à une classe de conserver les données:
public class DataHolder {
private String data;
public String getData() {return data;}
public void setData(String data) {this.data = data;}
private static final DataHolder holder = new DataHolder();
public static DataHolder getInstance() {return holder;}
}
De l'activité lancée:
String data = DataHolder.getInstance().getData();
Utiliser l'application singleton
Le singleton d'application est une instance android.app.Application
qui est créée lorsque l'application est lancée. Vous pouvez en fournir un personnalisé en étendant Application
:
import android.app.Application;
public class MyApplication extends Application {
private String data;
public String getData() {return data;}
public void setData(String data) {this.data = data;}
}
Avant de lancer l'activité:
MyApplication app = (MyApplication) getApplicationContext();
app.setData(someData);
Ensuite, à partir de l'activité lancée:
MyApplication app = (MyApplication) getApplicationContext();
String data = app.getData();
Champs statiques
L'idée est fondamentalement la même que celle du singleton, mais dans ce cas, vous fournissez un accès statique aux données:
public class DataHolder {
private static String data;
public static String getData() {return data;}
public static void setData(String data) {DataHolder.data = data;}
}
De l'activité lancée:
String data = DataHolder.getData();
HashMap of WeakReferences
Même idée, mais en permettant au garbage collector de supprimer les objets non référencés (par exemple lorsque l'utilisateur quitte l'activité):
public class DataHolder {
Map<String, WeakReference<Object>> data = new HashMap<String, WeakReference<Object>>();
void save(String id, Object object) {
data.put(id, new WeakReference<Object>(object));
}
Object retrieve(String id) {
WeakReference<Object> objectWeakReference = data.get(id);
return objectWeakReference.get();
}
}
Avant de lancer l'activité:
DataHolder.getInstance().save(someId, someObject);
De l'activité lancée:
DataHolder.getInstance().retrieve(someId);
Vous devrez peut-être ou non passer l'ID d'objet à l'aide des extras de l'intention. Tout dépend de votre problème spécifique.
Persister les objets sur le disque
L'idée est de sauvegarder les données sur disque avant de lancer l'autre activité.
Avantages: vous pouvez lancer l'activité à partir d'autres endroits et, si les données sont déjà persistantes, cela devrait fonctionner correctement.
Inconvénients: il est lourd et prend plus de temps à mettre en œuvre. Nécessite plus de code et donc plus de chances d'introduire des bogues. Ce sera également beaucoup plus lent.
Certaines des façons de conserver les objets incluent: