2010-06-09 5 views
18

Ich brauche ein Bild aus dem Internet herunterladen, in einem anderen Thread,
und dann in der Prozedur Nachricht, dass das Bildobjekt senden, auf den UI-Thread.Setzen Sie ein Objekt in Handler Nachricht

ich dies bereits haben:

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

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

handler.sendMessage(msg); 

Und wenn ich diese Meldung erhalten, Ich möchte das Objekt extrahieren:

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

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

Aber das gibt mir:

...java.lang.ClassCastException... 

Kann jemand helfen?

Und übrigens, ist dies der effizienteste Weg
ein Objekt an die UI Thread übergeben?

Danke euch allen!

Antwort

4

Ich würde eine AsyncTask für diese Art von Operation verwenden. Es ermöglicht Ihnen, in Ihrem UI-Thread für Dinge wie Fortschritt Updates und nachdem Sie Ihren Download abgeschlossen haben. Das folgende Beispiel zeigt, wie man getan werden sollte:

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

Hoffnung, die

5

Zuerst hilft: Wo genau Sie die Ausnahme bekommen Sie? Wenn Sie die Instanz in das Paket stecken oder wenn Sie sie abrufen?

Ich glaube, dass Sie Dinge vermischen. Wenn Ihr Paket erstellen, schreiben Sie

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

So werden Sie die Instanz „objet“ auf die Taste „MyObject“ zuweisen. Aber wenn Ihre Instanz zu erhalten schreiben Sie:

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

Hier finden Sie eine Instanz aus dem Schlüssel „IpTile“ abrufen. Beachten Sie, dass "IpTile" != "MyObject". Versuchen Sie es mit den folgenden abzurufen das Objekt:

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

oder anders herum, versuchen, Ihren Code zu ersetzen, die die Instanz in das Bündel mit diesem bringt:

Noch ein paar Punkte zu überprüfen:

  • Kann die Klasse MyObjectParcelable implementieren? (Ich nehme an, sonst könnten Sie nicht kompilieren)
  • Enthält die Variable object eine Instanz, die Parcelable implementiert?
65

Ich weiß, ich bin zu spät zur Party, aber es gibt einen einfacheren Weg, wenn Sie den Service in einem einzigen Prozess verwenden.Sie können jede beliebige Object auf Ihre Message befestigen Sie diese Zeile mit:

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

Dies funktioniert gut für mich in meiner aktuellen Projekte.
Oh, und ich bin weg von der Verwendung von AsyncTask Objekte, wie ich glaube, sie erhöhen Code-Kopplung zu viel.

+0

Necroposting Genießen Sie, aber diese Lösung führt zu unmöglich Gießen, wenn die Daten abzurufen versuchen. –

+12

So rufen Sie die Daten ab, die Sie benötigen: 'CustomObject passwordObject = (CustomObject) msg.obj;' – amp

+2

Aus dem offiziellen Dokument: Wenn Messenger die Nachricht über Prozesse hinweg sendet, kann sie nur null sein, wenn sie ein Parcelable enthält einer Framework-Klasse (nicht eine von der Anwendung implementiert). Für andere Datenübertragungen verwenden Sie setData (Bundle). Beachten Sie, dass parzellierbare Objekte hier nicht vor der FROYO-Version unterstützt werden. – Loda

1

Wenn Sie nur ein Objekt weiterleiten, können Sie dies mithilfe der Message-Klasse tun. Sie müssen kein Bündel erstellen - es ist einfacher und schneller.

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

mHandler.sendMessage(message); 

Abrufen es classicaly

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

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

:)

Verwandte Themen