views:

41

answers:

2

Hi!

I need to download an image from the internet, in a different thread,
and then send that image object in the handler message, to the UI thread.

I already have this:

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

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

handler.sendMessage(msg);

And when I receive this message, I want to extract the object:

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

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

But this is giving me:

...java.lang.ClassCastException...

Can anyone help?

And by the way, is this the most efficient way
to pass an object to the UI Thread?

Thank you all!

+1  A: 

I would use an AsyncTask for this kind of operation. It allows you to hook into your ui thread for things like progress updates and once you have finished your download. The example below shows how one should be done:

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

Hope that helps

disretrospect
+1  A: 

First: Where exactly do you get the exception? When putting the instance into the bundle, or upon retrieving it?

I believe your mixing things up. When creating your bundle, you write

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

So you are assigning the instance "objet " to the key "MyObject". But when retrieving your instance you write:

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

Here, you are retrieving an instance from the key "IpTile". Note that "IpTile" != "MyObject". Try using the following to retrieve the object:

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

or the other way around, try replacing your code which puts the instance into the bundle with this:

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

Another few points to check:

  • Does the class MyObject implement Parcelable? (I suppose so, otherwise you wouldn't be able to compile)
  • Does the variable object contain an instance which implements Parcelable?
exhuma