Android 在 Handler 消息中放入一个对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3004579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:14:30  来源:igfitidea点击:

Put an object in Handler message

androidhandlerparcelable

提问by Tsimmi

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.

我需要在不同的线程中从 Internet 下载图像,
然后在处理程序消息中将该图像对象发送到 UI 线程。

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?

顺便说一句,这是
将对象传递给 UI 线程的最有效方法吗?

Thank you all!

谢谢你们!

采纳答案by m6tt

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:

我会使用 AsyncTask 进行这种操作。它允许您连接到您的 ui 线程以进行诸如进度更新之类的事情,并且一旦您完成下载。下面的例子展示了一个人应该如何做:

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

希望有帮助

回答by Caspar Harmer

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 Objectto your Messageusing this line:

我知道我迟到了,但是如果您在单个流程中使用该服务,则有一种更简单的方法。您可以将任意Object的来Message使用这条线:

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 AsyncTaskobjects, as I believe they increase code coupling too much.

这在我当前的项目中对我来说效果很好。
哦,我正在远离使用AsyncTask对象,因为我相信它们会增加代码耦合太多。

回答by exhuma

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:

因此,您将实例“ objet”分配给键“ MyObject”。但是在检索您的实例时,您会这样写:

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:

在这里,您正在从键“ IpTile”中检索一个实例。请注意"IpTile" != "MyObject"。尝试使用以下方法检索对象:

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 MyObjectimplement Parcelable? (I suppose so, otherwise you wouldn't be able to compile)
  • Does the variable objectcontain an instance which implements Parcelable?
  • 该类是否MyObject实现Parcelable?(我想是的,否则你将无法编译)
  • 变量是否object包含一个实现的实例Parcelable

回答by tryp

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.

如果你只转发一个对象,你可以使用 Message 类来完成,你不需要创建一个包 - 它更容易和更快。

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 :)

享受 :)