Cómo enviar objetos a través del paquete

Necesito pasar una referencia a la clase que hace la mayoría de mi procesamiento a través de un paquete.

El problema es que no tiene nada que ver con intenciones o contextos y tiene una gran cantidad de objetos no primitivos. ¿Cómo puedo empaquetar la clase en un paquete / serializable y pasarla a startActivityForResult ?

Averiguar qué camino tomar requiere responder no solo a la pregunta clave de “¿por qué?” De CommonsWare, sino también a la pregunta “¿a qué?” lo estás pasando?

La realidad es que lo único que puede pasar por paquetes es la información simple; todo lo demás se basa en interpretaciones de lo que significan o apuntan esos datos. No se puede pasar literalmente un objeto, pero lo que se puede hacer es una de tres cosas:

1) Puede dividir el objeto en sus datos constitutivos, y si lo que está en el otro extremo tiene conocimiento del mismo tipo de objeto, puede armar un clon a partir de los datos serializados. Así es como la mayoría de los tipos comunes pasan a través de paquetes.

2) Puedes pasar un mango opaco. Si lo está pasando dentro del mismo contexto (aunque uno podría preguntar por qué molestarse) que será un identificador que puede invocar o eliminar la referencia. Pero si pasa a través de Binder a un contexto diferente, su valor literal será un número arbitrario (de hecho, estos números arbitrarios cuentan secuencialmente desde el inicio). No puede hacer nada más que seguirlo, hasta que vuelva al contexto original, lo que hará que Binder lo vuelva a transformar en el identificador original, haciéndolo útil de nuevo.

3) Puede pasar un identificador mágico, como un descriptor de archivo o una referencia a determinados objetos de OS / plataforma, y ​​si establece los indicadores correctos Binder creará un clon que apunta al mismo recurso para el destinatario, que realmente se puede usar en el otro extremo. Pero esto solo funciona para muy pocos tipos de objetos.

Lo más probable es que esté pasando su clase solo para que el otro lado pueda seguirla y devolvérselo más tarde, o la está pasando a un contexto donde se puede crear un clon a partir de datos constituyentes serializados … o bien estás tratando de hacer algo que simplemente no va a funcionar y debes replantear todo el enfoque.

También puede usar Gson para convertir un objeto a JSONObject y pasarlo al paquete. Para mí fue la forma más elegante que encontré para hacer esto. No he probado cómo afecta el rendimiento.

En actividad inicial

 Intent activity = new Intent(MyActivity.this,NextActivity.class); activity.putExtra("myObject", new Gson().toJson(myobject)); startActivity(activity); 

En la actividad siguiente

 String jsonMyObject; Bundle extras = getIntent().getExtras(); if (extras != null) { jsonMyObject = extras.getString("myObject"); } MyObject myObject = new Gson().fromJson(jsonMyObject, MyObject.class); 

La interfaz Parcelable es una buena forma de pasar un objeto con un Intento.

¿Cómo puedo hacer que mis objetos personalizados sean Parcelable? es una muy buena respuesta sobre cómo usar Parcelable

Los documentos oficiales de Google también incluyen un ejemplo

Podría usar el estado de aplicación global.

Actualizar:

Personaliza y luego agrega esto a tu AndroidManifest.xml:

  

Y luego tenga una clase en su proyecto como esta:

 package com.example; import android.app.Application; public class CustomApplication extends Application { public int someVariable = -1; } 

Y debido a que " se puede acceder a través de getApplication () desde cualquier actividad o servicio ", lo usa así:

 CustomApplication application = (CustomApplication)getApplication(); application.someVariable = 123; 

Espero que ayude.

También puede hacer que sus objetos sean serializables y usar los métodos getSerializable y putSerializable de Bundle.

Una forma más de enviar objetos a través del paquete es mediante el uso de bundle.putByteArray
Código de muestra

 public class DataBean implements Serializable { private Date currentTime; public setDate() { currentTime = Calendar.getInstance().getTime(); } public Date getCurrentTime() { return currentTime; } } 

poner Object of DataBean en Bundle:

 class FirstClass{ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //Your code... //When you want to start new Activity... Intent dataIntent =new Intent(FirstClass.this, SecondClass.class); Bundle dataBundle=new Bundle(); DataBean dataObj=new DataBean(); dataObj.setDate(); try { dataBundle.putByteArray("Obj_byte_array", object2Bytes(dataObj)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } dataIntent.putExtras(dataBundle); startActivity(dataIntent); } 

Conversión de objetos a matrices de bytes

 /** * Converting objects to byte arrays */ static public byte[] object2Bytes( Object o ) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream( baos ); oos.writeObject( o ); return baos.toByteArray(); } 

Recuperar Objeto del Paquete:

 class SecondClass{ DataBean dataBean; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //Your code... //Get Info from Bundle... Bundle infoBundle=getIntent().getExtras(); try { dataBean = (DataBean)bytes2Object(infoBundle.getByteArray("Obj_byte_array")); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 

Método para obtener objetos de matrices de bytes:

 /** * Converting byte arrays to objects */ static public Object bytes2Object( byte raw[] ) throws IOException, ClassNotFoundException { ByteArrayInputStream bais = new ByteArrayInputStream( raw ); ObjectInputStream ois = new ObjectInputStream( bais ); Object o = ois.readObject(); return o; } 

Espero que esto ayude a otros amigos.

Solución posible:

 Bundle bundle = new Bundle(); bundle.putSerializable("key", new CustomObject()); 

Clase CustomObject:

 class CustomObject implements Serializable{ private SubCustomObject1 sc1; private SubCustomObject2 sc2; } 

Subcustom objects:

 class SubCustomObject1 implements Serializable{ } class SubCustomObject2 implements Serializable{ } 

Esta es una respuesta muy tardía a mi propia pregunta, pero sigue recibiendo atención, por lo que siento que debo abordarla. La mayoría de estas respuestas son correctas y manejan el trabajo perfectamente. Sin embargo, depende de las necesidades de la aplicación. Esta respuesta se usará para describir dos soluciones a este problema.

Solicitud

La primera es la aplicación , ya que ha sido la respuesta más comentada aquí. La aplicación es un buen objeto para colocar entidades que necesitan una referencia a un contexto. Un `ServerSocket` indudablemente necesitaría un contexto (para E / S de archivos o actualizaciones simples de` ListAdapter`). Yo, personalmente, prefiero esta ruta. Me gustan las aplicaciones, son útiles para la recuperación de contexto (porque se pueden hacer estáticas y probablemente no causen una pérdida de memoria) y tienen un ciclo de vida simple.

Servicio

El Servicio` es segundo. Un `Servicio` es en realidad la mejor opción para mi problema, porque eso es lo que los servicios están diseñados para hacer:

 Un servicio es un componente de aplicación que puede realizar operaciones de larga ejecución en
 el fondo y no proporciona una interfaz de usuario.

Los servicios son claros ya que tienen un ciclo de vida más definido que es más fácil de controlar. Además, si es necesario, los servicios pueden ejecutarse externamente a la aplicación (es decir, al arrancar). Esto puede ser necesario para algunas aplicaciones o simplemente una característica ordenada.

Esta no era una descripción completa de ninguno, pero dejé enlaces a los documentos para aquellos que quieren investigar más. En general, el Service es mejor para la instancia que necesitaba, ejecutando un ServerSocket en mi dispositivo SPP.

Me encontré con esta pregunta cuando estaba buscando una forma de pasar un objeto Date. En mi caso, como se sugirió entre las respuestas, utilicé Bundle.putSerializable () pero eso no funcionaría para algo complejo como el DataManager descrito en la publicación original.

Mi sugerencia de que dará un resultado muy similar al colocar dicho DataManager en la Aplicación o convertirlo en Singleton es usar Dependency Injection y vincular el DataManager a un scope de Singleton e inyectar el DataManager donde sea necesario. No solo obtendrá el beneficio de una mayor capacidad de prueba, sino que también obtendrá un código más limpio sin todas las placas de la caldera “pasando dependencias entre clases y actividades”. (Robo) Es muy fácil trabajar con Guice y el nuevo marco Dagger parece prometedor también.

otra forma simple de pasar objetos usando un paquete:

  • en el objeto de clase, crea una lista estática u otra estructura de datos con una clave
  • cuando crea el objeto, póngalo en la lista / estructura de datos con la clave (es decir, la marca de tiempo larga cuando se crea el objeto)
  • crea el método getObject estático (tecla larga) para obtener el objeto de la lista
  • en el paquete, pase la clave para que pueda obtener el objeto más tarde desde otro punto del código

1.Un ejemplo muy directo y fácil de usar, hacer que el objeto a pasar implemente Serializable.

 class Object implements Serializable{ String firstName; String lastName; } 

2. pasar objeto en paquete

 Bundle bundle = new Bundle(); Object Object = new Object(); bundle.putSerializable("object", object); 
  1. obtener el objeto pasado del paquete como Serializable y luego enviarlo a Object.

    Object object = (Object) getArguments (). GetSerializable (“objeto”);