2010-06-09 18 views
18

Ho bisogno di scaricare un'immagine da internet, in un thread diverso,
e quindi inviare quell'oggetto immagine nel messaggio del gestore, al thread dell'interfaccia utente.Inserire un oggetto nel messaggio Handler

Ho già questo:

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

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

handler.sendMessage(msg); 

E quando ricevo questo messaggio, voglio estrarre l'oggetto:

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

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

Ma questo mi sta dando:

...java.lang.ClassCastException... 

Qualcuno può aiutare?

E, a proposito, è questo il modo più efficace per passare un oggetto al thread UI?
?

Grazie a tutti!

risposta

4

Vorrei utilizzare un AsyncTask per questo tipo di operazione. Ti permette di collegarti al tuo thread ui per cose come aggiornamenti di progresso e una volta che hai finito il download. L'esempio seguente mostra come si dovrebbe fare di più:

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

Speranza che aiuta

5

Primo: Dove esattamente si ottiene l'eccezione? Quando si inserisce l'istanza nel pacchetto o quando lo si recupera?

Credo che il vostro mescolare le cose. Quando si crea il pacchetto, si scrive

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

Così si sta assegnando l'istanza "objet" alla chiave "MyObject". Ma durante il recupero l'istanza si scrive:

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

Qui, si recupera un'istanza dal tasto "IpTile". Si noti che "IpTile" != "MyObject". Provare a utilizzare il seguente per recuperare l'oggetto:

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

o viceversa, provare a sostituire il codice che mette l'istanza in bundle con questo:

Ancora pochi punti da controllare:

  • La classe MyObject implementa Parcelable? (Suppongo di sì, altrimenti non saresti in grado di compilare)
  • La variabile object contiene un'istanza che implementa Parcelable?
65

So che sono in ritardo per la festa, ma c'è un modo più semplice se si utilizza il servizio all'interno di un singolo processo.È possibile allegare qualsiasi arbitrario Object al Message utilizzando questa linea:

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

Questo sta lavorando bene per me nei miei progetti in corso.
Oh, e mi sto allontanando dall'usare gli oggetti AsyncTask, perché credo che aumentino troppo l'accoppiamento del codice.

+0

Necroposting, ma questa soluzione porta alla fusione impossibile quando si cerca di recuperare i dati. –

+12

Per recuperare i dati necessari: 'CustomObject passedObject = (CustomObject) msg.obj;' – amp

+2

Dal documento ufficiale: Quando si utilizza Messenger per inviare il messaggio tra processi, questo può essere non nullo solo se contiene Parcelable di una classe di framework (non una implementata dall'applicazione). Per altri trasferimenti di dati usa setData (Bundle). Nota che gli oggetti Parcelable qui non sono supportati prima della versione FROYO. – Loda

1

Se si sta inoltrando solo un oggetto, è possibile farlo utilizzando la classe Messaggio, non è necessario creare un pacchetto: è più semplice e veloce.

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

mHandler.sendMessage(message); 

recuperarlo classicaly

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

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

Enjoy :)

Problemi correlati