¿Cómo enviar un objeto de una Actividad de Android a otra usando Intentos?

849

¿Cómo puedo pasar un objeto de un tipo personalizado de una Actividad a otra usando el putExtra()método de la clase Intent ?

UMAR
fuente
@UMMA: no necesita seguir marcando sus preguntas como "Wiki de la comunidad". Echa un vistazo aquí: meta.stackexchange.com/questions/11740/…
Dave Webb el
1
@Paresh: el enlace que proporcionó está roto. ¿podría por favor proporcionar una alternativa?
antiplex
Mira esta respuesta. stackoverflow.com/questions/8857546/…
Heitor Colangelo
Encontré un método simple y elegante stackoverflow.com/a/37774966/6456129
Yessy

Respuestas:

751

Si solo está pasando objetos, Parcelable fue diseñado para esto. Requiere un poco más de esfuerzo para usar que usar la serialización nativa de Java, pero es mucho más rápido (y quiero decir, MUCHO más rápido).

De los documentos, un ejemplo simple de cómo implementar es:

// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
    private int mData;

    /* everything below here is for implementing Parcelable */

    // 99.9% of the time you can just ignore this
    @Override
    public int describeContents() {
        return 0;
    }

    // write your object's data to the passed-in Parcel
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mData);
    }

    // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
        public MyParcelable createFromParcel(Parcel in) {
            return new MyParcelable(in);
        }

        public MyParcelable[] newArray(int size) {
            return new MyParcelable[size];
        }
    };

    // example constructor that takes a Parcel and gives you an object populated with it's values
    private MyParcelable(Parcel in) {
        mData = in.readInt();
    }
}

Observe que en el caso de que tenga más de un campo para recuperar de una Parcela determinada, debe hacerlo en el mismo orden en que los colocó (es decir, en un enfoque FIFO).

Una vez que haya implementado sus objetos Parcelable, es solo cuestión de ponerlos en sus Intentos con putExtra () :

Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);

Luego puede extraerlos con getParcelableExtra () :

Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");

Si su clase de objeto implementa Parcelable y Serializable, asegúrese de realizar una conversión a uno de los siguientes:

i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);
Jeremy Logan
fuente
14
¿Cómo se implementaría esto donde mData es un objeto (por ejemplo, JSONObject) y no un int?
Peter Ajtai
301
¿Por qué no puede pasar el objeto sin todo esto? Queremos pasar un objeto que ya está en la memoria.
ceklock
110
@tecnotron porque sus aplicaciones están en diferentes procesos y tienen espacios de direcciones de memoria separados, no puede enviar un puntero (referencia) al bloque de memoria en su proceso y esperar que esté disponible en otro proceso.
marcinj
12
¿Qué hago si no puedo hacer que la clase del objeto sea serializable o Parceable?
Amel Jose
11
@ceklock la razón detrás de esto es la siguiente: cuando la actividad se retrasa y luego se elimina de la memoria, y luego cuando el usuario la abre desde el menú reciente, tiene que crear la Actividad donde la dejó. Tiene que ser la misma IU. El objeto no está en la memoria en este caso. Pero la intención es.
tasomaniac
194

Tendrá que serializar su objeto en algún tipo de representación de cadena. Una posible representación de cadena es JSON, y una de las formas más fáciles de serializar a / desde JSON en Android, si me preguntas, es a través de Google GSON .

En ese caso, simplemente coloca el valor de retorno de cadena (new Gson()).toJson(myObject);y recupera el valor de cadena y lo usas fromJsonpara convertirlo nuevamente en tu objeto.

Sin embargo, si su objeto no es muy complejo, puede que no valga la pena la sobrecarga, y podría considerar pasar los valores separados del objeto en su lugar.

David Hedlund
fuente
19
Supongo que porque la respuesta de fiXedd resuelve el mismo problema sin el uso de bibliotecas externas, de una manera que es tan preferible, que nadie debería tener una razón para recurrir a la solución que proporcioné (inconsciente, en ese momento, de La brillante solución de fiXedd)
David Hedlund
55
Creo que eso es correcto. Además, JSON es un protocolo más apropiado para cliente / servidor y no hilo a hilo.
mobibob
16
No necesariamente es una mala idea, especialmente. dado que Gson es mucho más simple de usar que implementar parcelable para todos los objetos que desea enviar.
uvesten
77
como iam usando gson en mi aplicación, esta es una manera muy fácil y agradable.
Lars
16
Buena respuesta, aunque la solución completa sería String s = (new Gson().toJson(client));y luegoCli client = new Gson().fromJson(s, Cli.class);
Joaquin Iurchuk
155

Puede enviar objetos serializables a través de la intención

// send where details is object
ClassName details = new ClassName();
Intent i = new Intent(context, EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);


//receive
ClassName model = (ClassName) getIntent().getSerializableExtra("Editing");

And 

Class ClassName implements Serializable {
} 
Sridhar
fuente
2
También puede enviar objetos parcelables a través de la intención.
Tony Gil
66
"Serializable es cómicamente lento en Android. Borderline es inútil en muchos casos, de hecho". mira stackoverflow.com/questions/5550670/…
Seraphim's
¿Qué pasa si la actividad ya se está ejecutando? ¿Es necesario hacer startActivity (i); ? Quiero decir, ¿puedo hacer que la actividad A llame a la actividad B , y eso devuelve datos a la actividad A ? estoy confundido?
Francisco Corrales Morales
3
El rendimiento de @ Seraphim es importante si está serializando muchos objetos, pero el usuario no se dará cuenta si la serialización de un objeto tarda 1 ms o 10 ms. Si una intención adicional ya es Serializablepero no Parcelable, rara vez vale la pena hacerlo Parcelable.
Kevin Krumwiede
67

Para situaciones en las que sabe que pasará datos dentro de una aplicación, use "globales" (como clases estáticas)

Aquí es lo que Dianne Hackborn (hackbod - un ingeniero de software de Google Android) tenía que decir sobre el asunto:

Para situaciones en las que sabe que las actividades se ejecutan en el mismo proceso, simplemente puede compartir datos a través de globales. Por ejemplo, podría tener un global HashMap<String, WeakReference<MyInterpreterState>> y, cuando cree un nuevo MyInterpreterState, le aparecerá un nombre único y lo colocará en el mapa hash; para enviar ese estado a otra actividad, simplemente coloque el nombre único en el mapa hash y cuando se inicia la segunda actividad, puede recuperar MyInterpreterState del mapa hash con el nombre que recibe.

Peter Ajtai
fuente
25
Sí, me pareció extraño que nos den estos Intentos para usar, y luego un ingeniero superior nos dice que solo usemos globales para nuestros datos. Pero allí está directamente de la boca de los caballos.
Richard Le Mesurier
1
¿No sería una débil referencia aquí una víctima de la recolección de basura?
uLYsseus
1
@uLYsseus piensa que esa es la idea, una vez que hayas terminado con ellas en las actividades ... así que cuando se destruyan las actividades relevantes, esto permitirá que gc
Peter Ajtai
1
@RichardLeMesurier Estaba pensando lo mismo, pero luego busqué en la publicación de Grupos de Google mencionada anteriormente de Dianne Hackborn, y ella menciona que realmente el único problema con los globales sería cuando se usan intenciones implícitas (que pueden iniciar una actividad fuera de su paquete ) Esto tiene sentido, como menciona Dianne, porque esas actividades probablemente no tendrían conocimiento de los tipos personalizados que les está pasando. Una vez leí que, se hizo más claro para mí por qué globales podrían no ser una mala tal ruta, dadas las circunstancias, y pensé que iba a compartir en el caso de que otros eran demasiado curiosa
BMB
las intenciones fueron diseñadas en exceso hasta un punto en el que la intención podría pasar a una computadora diferente. lo cual obviamente no es una buena manera de hacer algo cuando en realidad solo tienes un proceso en el que te estás metiendo. Razones por las que no es bueno: uso de memoria, uso de CPU, uso de batería. el último hizo especialmente las elecciones de diseño con intenciones bastante desconcertantes en retrospectiva. hay personas que insisten en que son una buena idea, generalmente porque "google lo dijo".
Lassi Kinnunen
49

Su clase debe implementar Serializable o Parcelable.

public class MY_CLASS implements Serializable

Una vez hecho esto, puede enviar un objeto en putExtra

intent.putExtra("KEY", MY_CLASS_instance);

startActivity(intent);

Para obtener extras solo tienes que hacer

Intent intent = getIntent();
MY_CLASS class = (MY_CLASS) intent.getExtras().getSerializable("KEY");

Si su clase implementa Parcelable use next

MY_CLASS class = (MY_CLASS) intent.getExtras().getParcelable("KEY");

Espero que ayude: D

Pedro Romão
fuente
66
Su clase debe implementar Serializableestá mal. La clase puede implementar Parcelablepor ejemplo.
Marc Plano-Lesay
¿Cuál es la diferencia entre Parcelable y Serializable @Kernald? en términos de tiempo de procesamiento, ¿es más lento / no es la mejor práctica o algo así?
gumuruh
Si bien Serializablees una interfaz Java estándar, Parcelablees específica de Android. En términos de rendimiento, Parcelable es más eficiente: developerphil.com/parcelable-vs-serializable
Marc Plano-Lesay
35

Respuesta corta para una necesidad rápida

1. Implemente su clase en serializable.

¡Si tienes clases internas, no olvides implementarlas en Serializable también!

public class SportsData implements  Serializable
public class Sport implements  Serializable

List<Sport> clickedObj;

2. Pon tu objeto en Intención

 Intent intent = new Intent(SportsAct.this, SportSubAct.class);
            intent.putExtra("sport", clickedObj);
            startActivity(intent);

3. Y recibe tu objeto en la otra clase de actividad

Intent intent = getIntent();
    Sport cust = (Sport) intent.getSerializableExtra("sport");
Sam
fuente
ver este enlace, stackoverflow.com/questions/2139134/…
RejoylinLokeshwaran
Puede lograr lo mismo implementando la interfaz Parcelable. La interfaz parcelable tarda más tiempo en implementarse en comparación con Serializable debido al tamaño del código. Pero funciona más rápido que Serializable y usa menos recursos.
Kwnstantinos Nikoloutsos
27

Si su clase de objeto se implementa Serializable, no necesita hacer nada más, puede pasar un objeto serializable.
Eso es lo que uso.

Vlad
fuente
24

implementar serializable en su clase

public class Place implements Serializable{
        private int id;
        private String name;

        public void setId(int id) {
           this.id = id;
        }
        public int getId() {
           return id;
        }
        public String getName() {
           return name;
        }

        public void setName(String name) {
           this.name = name;
        }
}

Entonces puedes pasar este objeto con intención

     Intent intent = new Intent(this, SecondAct.class);
     intent.putExtra("PLACE", Place);
     startActivity(intent);

En la segunda actividad puedes obtener datos como este

     Place place= (Place) getIntent().getSerializableExtra("PLACE");

Pero cuando los datos se vuelven grandes, este método será lento.

Ishan Fernando
fuente
16

Puede usar Android BUNDLE para hacer esto.

Crea un paquete de tu clase como:

public Bundle toBundle() {
    Bundle b = new Bundle();
    b.putString("SomeKey", "SomeValue");

    return b;
}

Luego pase este paquete con INTENT. Ahora puede recrear su objeto de clase pasando paquetes como

public CustomClass(Context _context, Bundle b) {
    context = _context;
    classMember = b.getString("SomeKey");
}

Declare esto en su clase y uso personalizados.

om252345
fuente
1
Preferible a la implementación directa de Parcelable, en mi humilde opinión. Bundle implementa Parcelable por sí mismo para que aún tenga el aumento de rendimiento mientras evita todos los problemas para implementarlo usted mismo. En cambio, puede usar pares clave-valor para almacenar y recuperar los datos que son mucho más robustos que confiar en el mero orden.
Risadinha
Parcelable me parece complicado, en mi respuesta anterior estoy usando el método toBundle de la clase en su objeto, por lo que el objeto se convierte en paquete y luego podemos usar el constructor para convertir el paquete en objeto de clase.
om252345
Esta solución solo es viable si está pasando un solo objeto a través de una intención.
TheIT
Como json, pero json es ligero, creo.
David
¿El objeto cuando lo recupere será el mismo objeto o una copia?
Markus
16

Hay un par de formas por las cuales puede acceder a variables u objetos en otras clases o actividades.

A. Base de datos

B. preferencias compartidas.

C. serialización de objetos.

D. Una clase que puede contener datos comunes puede llamarse Utilidades comunes, depende de usted.

E. Pasando datos a través de Intentos e Interfaz Parcelable.

Depende de las necesidades de su proyecto.

A. Base de datos

SQLite es una base de datos de código abierto que está integrada en Android. SQLite admite características estándar de bases de datos relacionales como sintaxis SQL, transacciones y declaraciones preparadas.

Tutoriales: http://www.vogella.com/articles/AndroidSQLite/article.html

B. Preferencias compartidas

Supongamos que desea almacenar el nombre de usuario. Así que ahora habrá dos cosas, un Nombre de usuario clave , Valor Valor.

Cómo almacenar

 // Create an object of SharedPreferences.
 SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
 //now get Editor
 SharedPreferences.Editor editor = sharedPref.edit();
 //put your value
 editor.putString("userName", "stackoverlow");

 //commits your edits
 editor.commit();

Usando putString (), putBoolean (), putInt (), putFloat (), putLong () puede guardar su tipo de dta deseado.

Cómo buscar

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");

http://developer.android.com/reference/android/content/SharedPreferences.html

C. Serialización de objetos

La serialización de objetos se usa si queremos guardar un estado de objeto para enviarlo a través de la red o también puede usarlo para su propósito.

Use java beans y almacene en él como uno de sus campos y use getters y setter para eso

JavaBeans son clases Java que tienen propiedades. Piense en las propiedades como variables de instancia privada. Como son privados, la única forma en que se puede acceder desde fuera de su clase es a través de métodos en la clase. Los métodos que cambian el valor de una propiedad se llaman métodos setter, y los métodos que recuperan el valor de una propiedad se llaman métodos getter.

public class VariableStorage implements Serializable  {

    private String inString ;

    public String getInString() {
        return inString;
    }

    public void setInString(String inString) {
        this.inString = inString;
    }


}

Establezca la variable en su método de correo usando

VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);

Luego use la serialización de objetos para serializar este objeto y en su otra clase deserialice este objeto.

En la serialización, un objeto puede representarse como una secuencia de bytes que incluye los datos del objeto, así como información sobre el tipo de objeto y los tipos de datos almacenados en el objeto.

Después de que un objeto serializado se haya escrito en un archivo, puede leerse del archivo y deserializarse, es decir, la información de tipo y los bytes que representan el objeto y sus datos pueden usarse para recrear el objeto en la memoria.

Si desea un tutorial para esto, consulte este enlace

http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html

Obtener variable en otras clases

D. Utilidades comunes

Puede crear una clase usted mismo que puede contener datos comunes que necesita con frecuencia en su proyecto.

Muestra

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. Transferencia de datos a través de intentos

Consulte este tutorial para esta opción de pasar datos.

http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/

Nikhil Agrawal
fuente
Buen tutorial que mencionas en (E) sobre cómo pasar datos a través de Intents.
remrick
15

Gracias por la ayuda parcelable pero encontré una solución opcional más

 public class getsetclass implements Serializable {
        private int dt = 10;
    //pass any object, drwabale 
        public int getDt() {
            return dt;
        }

        public void setDt(int dt) {
            this.dt = dt;
        }
    }

En la actividad uno

getsetclass d = new getsetclass ();
                d.setDt(50);
                LinkedHashMap<String, Object> obj = new LinkedHashMap<String, Object>();
                obj.put("hashmapkey", d);
            Intent inew = new Intent(SgParceLableSampelActivity.this,
                    ActivityNext.class);
            Bundle b = new Bundle();
            b.putSerializable("bundleobj", obj);
            inew.putExtras(b);
            startActivity(inew);

Obtener datos en la actividad 2

 try {  setContentView(R.layout.main);
            Bundle bn = new Bundle();
            bn = getIntent().getExtras();
            HashMap<String, Object> getobj = new HashMap<String, Object>();
            getobj = (HashMap<String, Object>) bn.getSerializable("bundleobj");
            getsetclass  d = (getsetclass) getobj.get("hashmapkey");
        } catch (Exception e) {
            Log.e("Err", e.getMessage());
        }
usuario1140237
fuente
1
buena respuesta, pero aumente sus Estándares de codificación ... +1 aunque para traer Serializable en la competencia, sin embargo, los Parcelables son mucho más rápidos ...
Amit
13

Uso Gson con su API tan poderosa y simple para enviar objetos entre actividades,

Ejemplo

// This is the object to be sent, can be any object
public class AndroidPacket {

    public String CustomerName;

   //constructor
   public AndroidPacket(String cName){
       CustomerName = cName;
   }   
   // other fields ....


    // You can add those functions as LiveTemplate !
    public String toJson() {
        Gson gson = new Gson();
        return gson.toJson(this);
    }

    public static AndroidPacket fromJson(String json) {
        Gson gson = new Gson();
        return gson.fromJson(json, AndroidPacket.class);
    }
}

2 funciones las agrega a los objetos que desea enviar

Uso

Enviar objeto de A a B

    // Convert the object to string using Gson
    AndroidPacket androidPacket = new AndroidPacket("Ahmad");
    String objAsJson = androidPacket.toJson();

    Intent intent = new Intent(A.this, B.class);
    intent.putExtra("my_obj", objAsJson);
    startActivity(intent);

Recibir en B

@Override
protected void onCreate(Bundle savedInstanceState) {        
    Bundle bundle = getIntent().getExtras();
    String objAsJson = bundle.getString("my_obj");
    AndroidPacket androidPacket = AndroidPacket.fromJson(objAsJson);

    // Here you can use your Object
    Log.d("Gson", androidPacket.CustomerName);
}

Lo uso casi en todos los proyectos que hago y no tengo problemas de rendimiento.

MBH
fuente
Gracias, esto me ahorró horas de complicación excesiva.
Hristo Stoyanov
10

Luché con el mismo problema. Lo resolví usando una clase estática, almacenando los datos que quiero en un HashMap. En la parte superior, uso una extensión de la clase de actividad estándar donde he anulado los métodos onCreate on onDestroy para hacer que el transporte de datos y el borrado de datos estén ocultos. Hay que cambiar algunas configuraciones ridículas, por ejemplo, el manejo de orientación.

Anotación: No proporcionar objetos generales para pasar a otra Actividad es doloroso. Es como pegarse un tiro en la rodilla y esperar ganar 100 metros. "Parcable" no es un sustituto suficiente. Me hace reír ... No quiero implementar esta interfaz en mi API sin tecnología, ya que menos quiero introducir una nueva capa ... ¿Cómo podría ser que estamos en la programación móvil tan lejos de paradigma moderno ...

oopexpert
fuente
9

En tu primera actividad:

intent.putExtra("myTag", yourObject);

Y en tu segundo:

myCustomObject myObject = (myCustomObject) getIntent().getSerializableExtra("myTag");

No olvide hacer que su objeto personalizado sea serializable:

public class myCustomObject implements Serializable {
...
}
Rudi
fuente
¡Parcelable es mejor que serializable! ¡Evita usar Serializable en tu código de Android!
Filipe Brito
7

Otra forma de hacer esto es utilizar el Applicationobjeto (android.app.Application). Define esto en su AndroidManifest.xmlarchivo como:

<application
    android:name=".MyApplication"
    ...

Luego puede llamar a esto desde cualquier actividad y guardar el objeto en la Applicationclase.

En la primera actividad:

MyObject myObject = new MyObject();
MyApplication app = (MyApplication) getApplication();
app.setMyObject(myObject);

En SecondActivity, haga:

MyApplication app = (MyApplication) getApplication();
MyObject retrievedObject = app.getMyObject(myObject);

Esto es útil si tiene objetos que tienen un alcance de nivel de aplicación, es decir, deben usarse en toda la aplicación. losParcelable método es aún mejor si desea un control explícito sobre el alcance del objeto o si el alcance es limitado.

Sin Intentsembargo, esto evita el uso de todo. No sé si te quedan bien. Otra forma en que usé esto es hacer que los intidentificadores de los objetos se envíen a través de intentos y recuperen los objetos que tengo en Maps en el Applicationobjeto.

Saad Farooq
fuente
1
No es la forma correcta de hacer las cosas, ya que los objetos pueden ser variables, el tuyo puede funcionar si hablas de objetos estáticos a lo largo del ciclo de vida de la aplicación, pero algunas veces necesitamos objetos pasivos que pueden generarse usando el servicio web o stackoverflow.com / a / 2736612/716865
Muhannad A.Alhariri
Lo he usado con éxito con objetos generados a partir de servicios web al tener un ámbito de aplicación Mapdonde los objetos se almacenan y recuperan mediante el uso de un identificador. El único problema real con este enfoque es que Android borra la memoria después de un tiempo, por lo que debe verificar los nulos en su onResume (creo que los objetos pasados ​​en los intentos persisten, pero no estoy seguro). Aparte de eso, no veo que esto sea significativamente inferior.
Saad Farooq
Esta es la mejor respuesta. Muestra cómo diferentes actividades pueden hacer referencia al mismo modelo de datos. ¡Me llevó demasiado tiempo descubrir esto!
Markus
6

en su modelo de clase (Objeto) implemente Serializable, por ejemplo:

public class MensajesProveedor implements Serializable {

    private int idProveedor;


    public MensajesProveedor() {
    }

    public int getIdProveedor() {
        return idProveedor;
    }

    public void setIdProveedor(int idProveedor) {
        this.idProveedor = idProveedor;
    }


}

y tu primera actividad

MensajeProveedor mp = new MensajeProveedor();
Intent i = new Intent(getApplicationContext(), NewActivity.class);
                i.putExtra("mensajes",mp);
                startActivity(i);

y tu segunda actividad (NewActivity)

        MensajesProveedor  mensajes = (MensajesProveedor)getIntent().getExtras().getSerializable("mensajes");

¡¡buena suerte!!

revs David Hackro
fuente
6
public class SharedBooking implements Parcelable{

    public int account_id;
    public Double betrag;
    public Double betrag_effected;
    public int taxType;
    public int tax;
    public String postingText;

    public SharedBooking() {
        account_id = 0;
        betrag = 0.0;
        betrag_effected = 0.0;
        taxType = 0;
        tax = 0;
        postingText = "";
    }

    public SharedBooking(Parcel in) {
        account_id = in.readInt();
        betrag = in.readDouble();
        betrag_effected = in.readDouble();
        taxType = in.readInt();
        tax = in.readInt();
        postingText = in.readString();
    }

    public int getAccount_id() {
        return account_id;
    }
    public void setAccount_id(int account_id) {
        this.account_id = account_id;
    }
    public Double getBetrag() {
        return betrag;
    }
    public void setBetrag(Double betrag) {
        this.betrag = betrag;
    }
    public Double getBetrag_effected() {
        return betrag_effected;
    }
    public void setBetrag_effected(Double betrag_effected) {
        this.betrag_effected = betrag_effected;
    }
    public int getTaxType() {
        return taxType;
    }
    public void setTaxType(int taxType) {
        this.taxType = taxType;
    }
    public int getTax() {
        return tax;
    }
    public void setTax(int tax) {
        this.tax = tax;
    }
    public String getPostingText() {
        return postingText;
    }
    public void setPostingText(String postingText) {
        this.postingText = postingText;
    }
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(account_id);
        dest.writeDouble(betrag);
        dest.writeDouble(betrag_effected);
        dest.writeInt(taxType);
        dest.writeInt(tax);
        dest.writeString(postingText);

    }

    public static final Parcelable.Creator<SharedBooking> CREATOR = new Parcelable.Creator<SharedBooking>()
    {
        public SharedBooking createFromParcel(Parcel in)
        {
            return new SharedBooking(in);
        }
        public SharedBooking[] newArray(int size)
        {
            return new SharedBooking[size];
        }
    };

}

Pasando los datos:

Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
i.putParcelableArrayListExtra("data", (ArrayList<? extends Parcelable>) dataList);
intent.putExtras(bundle);
startActivity(intent);

Recuperando los datos:

Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");
Adnan Abdollah Zaki
fuente
5

La solución más fácil que encontré es ... crear una clase con miembros de datos estáticos con getters setters.

establecer de una actividad y obtener de otra actividad ese objeto.

actividad A

mytestclass.staticfunctionSet("","",""..etc.);

actividad b

mytestclass obj= mytestclass.staticfunctionGet();
UMAR
fuente
1
o crea una clase serializable para pasar a otra actividad lo que quieras pasar.
UMAR
99
Solo recuerda no poner objetos grandes y gordos. La vida útil de ese objeto será la misma que la vida útil de la aplicación. Y nunca almacene vistas. Este método también garantiza pérdidas de memoria.
Reno
1
Esta respuesta es útil pero no es una mejor solución en términos de memoria y optimización de recursos
Atul Bhardwaj
1
Esto rompe los principios de OOP al introducir variables globales. Nunca se sabe en qué estado se encuentran, si están configurados o no, son utilizados por muchos hilos y hay que lidiar con esta complejidad. Suele ser una buena pérdida de memoria, porque ni siquiera sabe cuándo liberar estas variables. No quiere decir que introduce un acoplamiento directo directo entre los diferentes módulos de la aplicación.
Afr
2
WTF? Las otras dos respuestas son muy superiores.
IcyFlame
4

puede usar los métodos putExtra (Serializable ..) y getSerializableExtra () para pasar y recuperar objetos de su tipo de clase; tendrá que marcar su clase Serializable y asegurarse de que todas sus variables miembro también sean serializables ...

nulo
fuente
4

Crear aplicación de Android

Archivo >> Nuevo >> Aplicación de Android

Ingrese el nombre del proyecto: android-pass-object-to-activity

Pakcage: com.hmkcode.android

Mantenga otras selecciones definitivas, vaya Siguiente hasta llegar a Finalizar

Antes de comenzar a crear la aplicación, necesitamos crear la clase POJO "Persona" que usaremos para enviar objetos de una actividad a otra. Tenga en cuenta que la clase está implementando la interfaz serializable.

Person.java

package com.hmkcode.android;
import java.io.Serializable;

public class Person implements Serializable{

    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

        // getters & setters....

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }   
}

Dos diseños para dos actividades

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/tvName"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center_horizontal"
        android:text="Name" />

    <EditText
        android:id="@+id/etName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:ems="10" >
        <requestFocus />
    </EditText>
</LinearLayout>

<LinearLayout
     android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
<TextView
    android:id="@+id/tvAge"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
    android:text="Age" />
<EditText
    android:id="@+id/etAge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10" />
</LinearLayout>

<Button
    android:id="@+id/btnPassObject"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="Pass Object to Another Activity" />

</LinearLayout>

activity_another.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
 >

<TextView
    android:id="@+id/tvPerson"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
 />

</LinearLayout>

Dos clases de actividad

1) ActivityMain.java

package com.hmkcode.android;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity implements OnClickListener {

Button btnPassObject;
EditText etName, etAge;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnPassObject = (Button) findViewById(R.id.btnPassObject);
    etName = (EditText) findViewById(R.id.etName);
    etAge = (EditText) findViewById(R.id.etAge);

    btnPassObject.setOnClickListener(this);
}

@Override
public void onClick(View view) {

    // 1. create an intent pass class name or intnet action name 
    Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");

    // 2. create person object
    Person person = new Person();
    person.setName(etName.getText().toString());
    person.setAge(Integer.parseInt(etAge.getText().toString()));

    // 3. put person in intent data
    intent.putExtra("person", person);

    // 4. start the activity
    startActivity(intent);
}

}

2) AnotherActivity.java

package com.hmkcode.android;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class AnotherActivity extends Activity {

TextView tvPerson;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_another);

    // 1. get passed intent 
    Intent intent = getIntent();

    // 2. get person object from intent
    Person person = (Person) intent.getSerializableExtra("person");

    // 3. get reference to person textView 
    tvPerson = (TextView) findViewById(R.id.tvPerson);

    // 4. display name & age on textView 
    tvPerson.setText(person.toString());

}
}
MFP
fuente
4

Usando la biblioteca Gson de Google, puede pasar objetos a otras actividades. De hecho, convertiremos objetos en forma de cadena json y después de pasar a otra actividad volveremos a convertir a objetos como este

Considere una clase de frijol como esta

 public class Example {
    private int id;
    private String name;

    public Example(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Necesitamos pasar el objeto de la clase Example

Example exampleObject=new Example(1,"hello");
String jsonString = new Gson().toJson(exampleObject);
Intent nextIntent=new Intent(this,NextActivity.class);
nextIntent.putExtra("example",jsonString );
startActivity(nextIntent);

Para leer necesitamos hacer la operación inversa en NextActivity

 Example defObject=new Example(-1,null);
    //default value to return when example is not available
    String defValue= new Gson().toJson(defObject);
    String jsonString=getIntent().getExtras().getString("example",defValue);
    //passed example object
    Example exampleObject=new Gson().fromJson(jsonString,Example .class);

Agregue esta dependencia en gradle

compile 'com.google.code.gson:gson:2.6.2'
Jinesh Francis
fuente
3
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
startACtivity(i);
Manas Ranjan
fuente
3

Sé que es tarde pero es muy simple. Todo lo que tienes que hacer es dejar que tu clase implemente Serializable como

public class MyClass implements Serializable{

}

entonces puedes pasar a una intención como

Intent intent=......
MyClass obje=new MyClass();
intent.putExtra("someStringHere",obje);

Para obtenerlo, simplemente llame

MyClass objec=(MyClass)intent.getExtra("theString");
suulisina
fuente
2

Si de todos modos tiene una clase singleton (servicio fx) que actúa como puerta de entrada a la capa de su modelo, puede resolverse teniendo una variable en esa clase con captadores y establecedores para ella.

En la actividad 1:

Intent intent = new Intent(getApplicationContext(), Activity2.class);
service.setSavedOrder(order);
startActivity(intent);

En la actividad 2:

private Service service;
private Order order;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quality);

    service = Service.getInstance();
    order = service.getSavedOrder();
    service.setSavedOrder(null) //If you don't want to save it for the entire session of the app.
}

En servicio:

private static Service instance;

private Service()
{
    //Constructor content
}

public static Service getInstance()
{
    if(instance == null)
    {
        instance = new Service();
    }
    return instance;
}
private Order savedOrder;

public Order getSavedOrder()
{
    return savedOrder;
}

public void setSavedOrder(Order order)
{
    this.savedOrder = order;
}

Esta solución no requiere ninguna serialización u otro "empaque" del objeto en cuestión. Pero solo será beneficioso si está utilizando este tipo de arquitectura de todos modos.

Kitalda
fuente
¿Cuáles son las desventajas de este enfoque? Parece tan lógico y delgado. Siempre leo que no debes hacer eso, pero nunca recibo una buena explicación sobre lo que podría salir mal.
Markus
Como ya no puedo editar mi comentario: ¿no es esta la única solución posible para obtener una referencia a un objeto en lugar de una copia? ¡Necesito recuperar el mismo objeto y no una copia!
Markus
Creo que esto está algo desanimado debido al alto acoplamiento al que conduce. Pero sí, hasta donde puedo ver, este enfoque es el más viable si necesita el objeto real. Como siempre en la programación, puedes hacer lo que quieras, solo debes hacerlo con cuidado. Esta solución funcionó para mí, y la prefiero ya que de todos modos uso esa arquitectura.
Kitalda
En realidad, terminé ampliando la clase de aplicación y almacené mi modelo de datos allí. En los Intentos, solo transmití la ID de los objetos de datos que podrían usarse para recuperar el objeto original de la clase Aplicación. Además, la clase de aplicación extendida notifica a todos los objetos que usan el modelo de datos si cambia a través de un concepto de escucha estándar. Sé que esto se ajusta solo a mi caso en el que necesito compartir un modelo de datos en toda la aplicación, ¡pero para ese caso es perfecto y no se necesitan clases y campos estáticos también!
Markus
2

De lejos, la forma más fácil en mi humilde opinión de parcelar objetos. Simplemente agregue una etiqueta de anotación sobre el objeto que desea convertir en parcelable.

Un ejemplo de la biblioteca está debajo de https://github.com/johncarl81/parceler

@Parcel
public class Example {
    String name;
    int age;

    public Example(){ /*Required empty bean constructor*/ }

    public Example(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public String getName() { return name; }

    public int getAge() { return age; }
}
Ryan
fuente
2

Primero implemente Parcelable en su clase. Luego pase un objeto como este.

SendActivity.java

ObjectA obj = new ObjectA();

// Set values etc.

Intent i = new Intent(this, MyActivity.class);
i.putExtra("com.package.ObjectA", obj);

startActivity(i);

ReceiveActivity.java

Bundle b = getIntent().getExtras();
ObjectA obj = b.getParcelable("com.package.ObjectA");

La cadena del paquete no es necesaria, solo la cadena debe ser la misma en ambas Actividades

REFERENCIA

Arpit Patel
fuente
2

Inicie otra actividad desde esta actividad pasando parámetros a través de Bundle Object

Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "[email protected]");
startActivity(intent);

Recuperar en otra actividad (YourActivity)

String s = getIntent().getStringExtra("USER_NAME");

Esto está bien para un tipo de datos simple y amable. Pero si desea pasar datos complejos entre actividades, primero debe serializarlos.

Aquí tenemos el modelo de empleado

class Employee{
    private String empId;
    private int age;
    print Double salary;

    getters...
    setters...
}

Puede usar Gson lib proporcionado por google para serializar datos complejos como este

String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);

Bundle bundle = getIntent().getExtras();
    String empStr = bundle.getString("EMP");
            Gson gson = new Gson();
            Type type = new TypeToken<Employee>() {
            }.getType();
            Employee selectedEmp = gson.fromJson(empStr, type);
usuario1101821
fuente
2

En Koltin

Agregue la extensión kotlin en su build.gradle.

apply plugin: 'kotlin-android-extensions'

android {
    androidExtensions {
        experimental = true
   }
}

Luego cree su clase de datos de esta manera.

@Parcelize
data class Sample(val id: Int, val name: String) : Parcelable

Pasar objeto con intención

val sample = Sample(1,"naveen")

val intent = Intent(context, YourActivity::class.java)
    intent.putExtra("id", sample)
    startActivity(intent)

Obtener objeto con intención

val sample = intent.getParcelableExtra("id")
Naveen
fuente
¿Sigue siendo experimental?
ShadeToD
2

La forma más fácil y Java de hacerlo es: implementar serializable en su clase pojo / modelo

Recomendado para Android para la vista de rendimiento: hacer que el modelo sea parcelable

Ashok Kumar
fuente
1

Lo más simple sería usar lo siguiente donde el elemento es una cadena:

intent.putextra("selected_item",item)

Para recibir:

String name = data.getStringExtra("selected_item");
ankish
fuente
3
es solo para cadenas, enteros, etc., pero quiero que el objeto y el uso de objetos estáticos solo sea posible.
UMAR