将对象放入Handler消息中

Tsi*_*mmi 20 android handler parcelable

我需要从互联网上下载一个图像,在另一个线程中,
然后将处理程序消息中的图像对象发送到UI线程.

我已经有了这个:

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

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

handler.sendMessage(msg);
Run Code Online (Sandbox Code Playgroud)

当我收到此消息时,我想提取对象:

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

    MyObject objectRcvd = (MyObject) msg.getData().getParcelable("IpTile");
    addToCache(ipTile);
    mapView.invalidate();
}
Run Code Online (Sandbox Code Playgroud)

但是这给了我:

...java.lang.ClassCastException...
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙吗?

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

谢谢你们!

Cas*_*mer 69

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

msg.obj = new CustomObject() // or whatever object you like
Run Code Online (Sandbox Code Playgroud)

在我目前的项目中,这对我很有用.
哦,我正在远离使用AsyncTask对象,因为我相信它们会增加代码耦合太多.

  • 要检索您只需要的数据:`CustomObject passedObject =(CustomObject)msg.obj;` (14认同)
  • 从官方文档:当使用Messenger跨进程发送消息时,如果它包含框架类的Parcelable(不是由应用程序实现的那个),则它只能是非null.对于其他数据传输,请使用setData(Bundle).请注意,在FROYO版本发布之前,不支持此处的Parcelable对象. (2认同)

exh*_*uma 7

第一:你究竟在哪里获得例外?将实例放入包中或检索它时?

我相信你的混合了.在创建捆绑包时,您可以编写

b.putParcelable("MyObject", (Parcelable) object);
Run Code Online (Sandbox Code Playgroud)

因此,您将实例" objet" 分配给键" MyObject".但是在检索你的实例时你会写:

MyObject objectRcvd = (MyObject) msg.getData().getParcelable("IpTile");
Run Code Online (Sandbox Code Playgroud)

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

MyObject objectRcvd = (MyObject) msg.getData().getParcelable("MyObject");
Run Code Online (Sandbox Code Playgroud)

或者反过来,尝试替换将实例放入捆绑包中的代码:

b.putParcelable("IpTile", (Parcelable) object);
Run Code Online (Sandbox Code Playgroud)

另外几点要检查:

  • 该课程是否MyObject实施Parcelable?(我想是的,否则你将无法编译)
  • 变量是否object包含实现的实例Parcelable


m6t*_*6tt 4

我会使用 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

希望有帮助