J'ai un problème étrange. Je regardais autour du Web mais je n'ai pas trouvé de réponse. Je suis toujours un débutant en programmation Android. Alors allons-y:
Tout ce que je veux faire, c'est appeler la deuxième activité avec des données. Cela fonctionne très bien avec de petites données, mais si les données deviennent volumineuses, la deuxième activité ne s'affichera pas et la première se terminera. Voici mon code de la méthode d'appel:
Intent intent = new Intent(ActivitySearch.this,ActivityResults.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("data", searchList);
intent.putExtras(bundle);
startActivity(intent);
La partie de la réception des données n'est pas importante. Même si je n'essaie pas de lire le bundle, l'activité ne sera pas appelée. J'ai testé cela avec les lignes suivantes:
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d("DEBUG","ActivityResult::onCreate()");
super.onCreate(savedInstanceState);
OnCreate()
n'est jamais appelé.
Peut-être que l'un des vôtres a eu une idée ... Merci de votre aide!
Edit: au moins j'ai oublié: cela ne se produit que sous ICS. L'application fonctionne comme un charme avec du pain d'épice et du froyo.
Edit2: Logcat
10-10 14:49:46.951: D/OpenGLRenderer(21696): Flushing caches (mode 0)
10-10 14:49:47.011: V/ActivityThread(22429): com.example.amazonsearch white listed for hwui
10-10 14:49:50.821: W/IInputConnectionWrapper(21696): showStatusIcon on inactive InputConnection
Vous obtenez probablement TransactionTooLargeException
Comme suggéré par Google guide Android , vous pouvez utiliser des champs statiques ou des singletons pour partager des données entre les activités.
Ils le recommandent "Pour partager des objets définis par l'utilisateur complexes non persistants pendant une courte durée"
D'après votre code, il semble que c'est exactement ce dont vous avez besoin.
Ainsi, votre code dans ActivitySearch.class pourrait ressembler à ceci:
ActivityResults.data = searchList;
Intent intent = new Intent(ActivitySearch.this,ActivityResults.class);
startActivity(intent);
Ensuite, vous pouvez accéder à ActivityResults.data de n'importe où dans l'activité ActivityResults après son démarrage.
Pour les données qui doivent être partagées entre les sessions utilisateur, il n'est pas conseillé d'utiliser des champs statiques, car le processus d'application pourrait être tué et redémarré par Android framework pendant que l'application s'exécute en arrière-plan (si le framework doit Dans ce cas, tous les champs statiques seront réinitialisés.
La façon dont je préfère transmettre des données volumineuses consiste à utiliser des énumérations . Quelques avantages de cette approche:
Voici un exemple:
package com.jyvee.arguments;
import Java.util.List;
import Android.app.Activity;
import Android.content.Context;
import Android.content.Intent;
import Android.os.Bundle;
public class SomeActivity extends Activity {
// Names for the arguments we pass to the
// activity when we create it
private final static String ARG_STRING = "ARG_STRING";
private final static String ARG_INT = "ARG_INT";
private String stringField;
private int intField;
private List<Object> arrayField;
private enum DataHolder {
INSTANCE;
private List<Object> mObjectList;
public static boolean hasData() {
return INSTANCE.mObjectList != null;
}
public static void setData(final List<Object> objectList) {
INSTANCE.mObjectList = objectList;
}
public static List<Object> getData() {
final List<Object> retList = INSTANCE.mObjectList;
INSTANCE.mObjectList = null;
return retList;
}
}
@Override
protected void onCreate(final Bundle savedState) {
super.onCreate(savedState);
// Get the activity intent if there is a one
final Intent intent = getIntent();
// And retrieve arguments if there are any
if (intent.hasExtra(ARG_STRING)) {
stringField = intent.getExtras().getString(ARG_STRING);
}
if (intent.hasExtra(ARG_INT)) {
intField = intent.getExtras().getInt(ARG_INT);
}
// And we retrieve large data from enum
if (DataHolder.hasData()) {
arrayField = DataHolder.getData();
}
// Now stringField, intField fields are available
// within the class and can be accessed directly
}
/**
* /** A static method for starting activity with supplied arguments
*
* @param contextA
* context that starts this activity
* @param stringArg
* A string argument to pass to the new activity
* @param intArg
* An int argument to pass to the new activity
* @param objectList
* An object list argument to pass to the new activity
*/
public static void startActivity(final Context context, final String stringArg,
final int intArg, final List<Object> objectList) {
// Initialize a new intent
final Intent intent = new Intent(context, SomeActivity.class);
// To speed things up :)
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
// And add arguments to the Intent
intent.putExtra(ARG_STRING, stringArg);
intent.putExtra(ARG_INT, intArg);
// Now we put the large data into our enum instead of using Intent extras
DataHolder.setData(objectList);
context.startActivity(intent);
}
}
Plus d'informations ici .
Si vous transmettez une grande information d'une activité à une autre, cela peut ralentir l'application
mais utilisez Global Class pour stocker des variables en utilisant que vous pouvez facilement obtenir ou définir toutes les valeurs
qui a déclaré dans le fichier global
voir ce lien:
http://androidresearch.wordpress.com/2012/03/22/defining-global-variables-in-Android/
Pour autant que je m'en souvienne, jusqu'à l'API-8 (Froyo), il y avait certaines limitations (comme 1 Mo) lors du passage d'objets parcelables à travers des intentions. Cependant, vous pouvez simplement noter vos données parcellaires dans un fichier et envoyer le chemin du fichier à votre prochaine activité via le bundle. Plus tard, codez votre deuxième activité pour lire les données du fichier et supprimez-les ensuite.
Je ne sais pas pourquoi cela ne fonctionne pas avec des données volumineuses, mais si vous ne trouvez aucun moyen de le corriger, je vous suggère d'utiliser une application globale personnalisée, comme ici . (Vérifiez également la bonne réponse pour que cela fonctionne)