2012-10-10 31 views
24

Tengo un problema extraño. Estaba buscando por la web pero no encontré una respuesta. Todavía soy un principiante en la programación de Android. Así que vamos:Problema: transferir datos grandes a la segunda actividad

Todo lo que quiero hacer es llamar a la segunda Actividad con algunos datos. Funciona bien con datos pequeños, pero si los datos son grandes, la segunda actividad no se mostrará y la primera finalizará. Aquí está mi código del método de llamada:

Intent intent = new Intent(ActivitySearch.this,ActivityResults.class); 
Bundle bundle = new Bundle(); 
bundle.putParcelableArrayList("data", searchList); 
intent.putExtras(bundle); 
startActivity(intent); 

La parte de recepción de datos no es importante. Incluso si no intento leer el paquete, no se ejecutará la actividad. He probado esto con las líneas siguientes:

@Override 
public void onCreate(Bundle savedInstanceState) { 
Log.d("DEBUG","ActivityResult::onCreate()"); 
super.onCreate(savedInstanceState); 

OnCreate() no es llamado.

Tal vez uno de ustedes tuvo una idea ... ¡Gracias por su ayuda!

Editar: al menos lo olvidé: esto solo ocurre bajo ICS. La aplicación funciona como un encanto con gingerbread y 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 
+0

Bueno, en este caso debes tener stacktrace en LogCat. Por favor revise y vacíe un registro de error. –

+0

bien, lo adjunté a la publicación. ¡Gracias por esta respuesta rápida! – sk2andy

+1

Habrá más. Aquí no puedo ver ninguna información relevante –

Respuesta

33

Usted probablemente está recibiendo TransactionTooLargeException

Según lo sugerido por Google android guide, podría utilizar campos estáticos o únicos para compartir datos entre las actividades.

la recomiendan "Para compartir objetos definidos por el usuario no persistentes complejos de corta duración"

Desde su código parece que es exactamente lo que necesita.

Así que su código en ActivitySearch.class podría ser algo como esto:

ActivityResults.data = searchList; 
Intent intent = new Intent(ActivitySearch.this,ActivityResults.class); 
startActivity(intent); 

Entonces se puede acceder desde cualquier lugar ActivityResults.data actividad ActivityResults después de iniciarse.

Para los datos que deben compartirse entre sesiones de usuario, no es aconsejable usar campos estáticos, dado que el proceso de aplicación puede ser destruido y reiniciado por android framework mientras la aplicación se ejecuta en segundo plano (si el framework necesita liberar recursos). En tal caso, todos los campos estáticos se reiniciarán.

+2

¿Qué sucede si desea enviar datos de gran tamaño entre diferentes aplicaciones o procesos? –

+0

Sí, se lanza TTLE con la mayor probabilidad. La solución puede ser tan simple como usar Serializable en su lugar. Más información aquí http://nemanjakovacevic.net/blog/english/2015/03/24/yet-another-post-on-serializable-vs-parcelable/ –

+1

Creo que la sugerencia de Android de utilizar una clase Singleton para grandes datos temporales es una excelente manera de ir. Lo mantiene de manera rápida y simple, con control total de dónde están sus datos. – mix3d

2

Si pasa un Grande Información de una a otra actividad puede ser entonces que hacer la aplicación más lento

pero el uso de Clase Mundial para almacenar variables con el uso que usted puede conseguir fácilmente o establece valores

que declaró en el archivo global

ver este enlace:

http://androidresearch.wordpress.com/2012/03/22/defining-global-variables-in-android/

+0

bien, este es el trabajo en el que tengo que pensar. ¡Muchas gracias! – sk2andy

+0

No es realmente una solución pero la implementación correcta, creo: no debe transferir grandes cantidades de datos de una actividad a la otra. – Teovald

1

Por lo que yo recordaba, hasta el API-8 (Froyo), hubo algunas limitaciones (como 1 MB) al pasar objetos parcelable a través de intentos. Sin embargo, puede simplemente anotar los datos que se pueden empacar en un archivo y enviar la ruta del archivo a su siguiente actividad a través del paquete. Más tarde, codifique su segunda actividad para leer los datos del archivo y eliminarlos después.

+0

tal vez, tenga que pensarlo. ¡Gracias! – sk2andy

+0

las referencias globales atraen suficiente y es un atajo, pero no es algo recomendado para grandes cantidades de datos. – waqaslam

+3

Todavía hay un límite hoy, en Lollipop, y puede ser mucho menor que 1MB. Escribí una publicación de blog arrojando algo de luz sobre la situación http://nemanjakovacevic.net/blog/english/2015/03/24/yet-another-post-on-serializable-vs-parcelable/ –

0

No tengo idea de por qué no funciona con datos grandes, pero si no encuentra ninguna manera de solucionarlo, le sugiero que utilice una aplicación global personalizada, like here. (También puedes ver la respuesta correcta para que funcione)

+0

bien, este es un posible solución alternativa Asumiré que lo haga. ¡Muchas gracias! – sk2andy

23

La forma en que prefiero pasar datos grandes es mediante el uso de enumeraciones. Algunas de las ventajas de este enfoque:

  • No hay necesidad de crear conjuntos unitarios, que siempre tienen una sola instancia de la enumeración;
  • Los datos están encapsulados correctamente; se elimina
  • Referencia justo después de la actividad que recibe

He aquí un ejemplo:

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); 
    } 
} 

Más información here.

+0

¡Funcionó para mí! :) –

+0

aprecia su solución :) – Nisarg

+0

¿Esto utiliza la serialización enum? ¿Cómo es el rendimiento en comparación con el enfoque singleton? –

Cuestiones relacionadas