问题
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:
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
回答2:
I know I'm late to the party, but there is an easier way if you are using the service within a single process. You can attach any arbitrary Object
to your Message
using this line:
msg.obj = new CustomObject() // or whatever object you like
This is working well for me in my current projects.
Oh, and I'm moving away from using AsyncTask
objects, as I believe they increase code coupling too much.
回答3:
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
implementParcelable
? (I suppose so, otherwise you wouldn't be able to compile) - Does the variable
object
contain an instance which implementsParcelable
?
回答4:
If you are forwarding only one object, you can do it using the Message class, you don't need to create a bundle - it's easier and faster.
Object myObject = new Object();
Message message = new Message();
message.obj = myObject;
message.what = 0;
mHandler.sendMessage(message);
Retrieve it classicaly
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// ...
Object object = (Object) msg.obj;
}
Enjoy :)
来源:https://stackoverflow.com/questions/3004579/put-an-object-in-handler-message