2010-06-09 9 views
18

Necesito descargar una imagen de Internet, en un hilo diferente,
y luego enviar ese objeto de imagen en el mensaje del manejador, al hilo de UI.Poner un objeto en el mensaje del manejador

Ya tengo esto:

... 
Message msg = Message.obtain(); 

Bundle b = new Bundle(); 
b.putParcelable("MyObject", (Parcelable) object); 
msg.setData(b); 

handler.sendMessage(msg); 

Y cuando recibo este mensaje, Quiero extraer el objeto:

... 
public void handleMessage(Message msg) { 
    super.handleMessage(msg); 

    MyObject objectRcvd = (MyObject) msg.getData().getParcelable("IpTile"); 
    addToCache(ipTile); 
    mapView.invalidate(); 
} 

Pero esto me está dando:

...java.lang.ClassCastException... 

¿Alguien puede ayudar?

Y, por cierto, ¿es esta la forma más eficiente de
para pasar un objeto al subproceso de UI?

¡Gracias a todos!

Respuesta

4

Utilizaría un AsyncTask para este tipo de operación. Te permite conectar tu hilo de la interfaz de usuario para cosas como actualizaciones de progreso y una vez que hayas terminado la descarga. El ejemplo siguiente muestra cómo uno se debe hacer:

class GetImageTask extends AsyncTask<String, int[], Bitmap> { 

    @Override 
    protected Bitmap doInBackground(String... params) { 
    Bitmap bitmap = null; 

    // Anything done here is in a seperate thread to the UI thread 
    // Do you download from here 

    // If you want to update the progress you can call 
    publishProgress(int progress); // This passes to the onProgressUpdate method 

    return bitmap; // This passes the bitmap to the onPostExecute method 
    } 

    @Override 
    protected void onProgressUpdate(Integer... progress) { 
    // This is on your UI thread, useful if you have a progressbar in your view 
    } 

    @Override 
    protected void onPostExecute(Bitmap bitmapResult) { 
    super.onPostExecute(bitmapResult); 
    // This is back on your UI thread - Add your image to your view 
    myImageView.setImageBitmap(bitmapResult); 
    } 
} 

Espero que ayude

5

En primer lugar: ¿Dónde exactamente se puede conseguir excepción? ¿Al poner la instancia en el paquete, o al recuperarlo?

Creo que estás mezclando cosas. Al crear su paquete, se escribe

b.putParcelable("MyObject", (Parcelable) object); 

Así está asignando la instancia "objet" a la tecla "MyObject". Sin embargo, al recuperar la instancia se escribe:

MyObject objectRcvd = (MyObject) msg.getData().getParcelable("IpTile"); 

Aquí, va a recuperar una instancia de la clave "IpTile". Tenga en cuenta que "IpTile" != "MyObject". Intente utilizar el siguiente a recuperar el objeto:

MyObject objectRcvd = (MyObject) msg.getData().getParcelable("MyObject"); 

o al revés, intente reemplazar el código que pone la instancia en el haz con esto:

Unos pocos puntos a comprobar:

  • ¿La clase MyObject implementa Parcelable? (Supongo que, de lo contrario no sería capaz de compilar)
  • ¿La variable de object contienen una instancia que implementa Parcelable?
65

Sé que llego tarde a la fiesta, pero hay una manera más fácil si está utilizando el servicio en un solo proceso.Puede adjuntar cualquier arbitraria Object a su Message usando esta línea:

msg.obj = new CustomObject() // or whatever object you like 

Esto funciona bien para mí en mis proyectos actuales.
Ah, y me estoy alejando del uso de objetos AsyncTask, ya que creo que aumentan demasiado el acoplamiento de código.

+0

Necroposting, pero esta solución conduce a la fundición imposible cuando se trata de recuperar los datos. –

+12

Para recuperar los datos que solo necesita: 'CustomObject passedObject = (CustomObject) msg.obj;' – amp

+2

Del doc oficial: Al usar Messenger para enviar el mensaje a través de los procesos, esto solo puede ser no nulo si contiene un Parcelable de una clase de marco (no implementada por la aplicación). Para otra transferencia de datos use setData (Bundle). Tenga en cuenta que los objetos Parcelable aquí no son compatibles antes de la versión FROYO. – Loda

1

Si está reenviando solo un objeto, puede hacerlo utilizando la clase Message, no necesita crear un paquete, es más fácil y más rápido.

Object myObject = new Object(); 
Message message = new Message(); 
message.obj = myObject; 
message.what = 0; 

mHandler.sendMessage(message); 

recuperarlo clásicamente

@Override 
public void handleMessage(Message msg) { 
    super.handleMessage(msg); 

    // ... 
    Object object = (Object) msg.obj; 
} 

Disfruta :)

Cuestiones relacionadas