将对象从服务发送到活动(无法封送非Parcelable)

时间:2011-07-06 12:23:04

标签: java android runtimeexception

我正在尝试将数据从我的活动发送到服务并收回一些信息,但我得到了:

  

java.lang.RuntimeException:不能   整理非Parcelable对象   过程

活动中的代码如下所示:

Message msg = Message.obtain(null, 1);
    msg.obj=1;
    msg.replyTo=new Messenger(new PlanRequestIncomingHandler());
    try {
        msgService.send(msg);
    } catch (RemoteException e) {
        Log.i(tag, "Can not send msg to service");
        e.printStackTrace();
    }

当我设置msg.obj = something时,我得到java.lang.RuntimeException,有人可以帮帮我吗?

5 个答案:

答案 0 :(得分:8)

您可以通过Messenger传递Parcelable类型的对象。或者,如果您想通过primitive data types使用Bundle包装,如下所示。

在服务端:

//Create a bundle object and put your data in it
Bundle bundle = new Bundle();
bundle.putInt("key", 1);

Message msg = Message.obtain(null, 123);
msg.obj = bundle;
msg.replyTo = new Messenger(new PlanRequestIncomingHandler());
try {
    msgService.send(msg);
} catch (RemoteException e) {
    Log.i(tag, "Can't send msg to service");
    e.printStackTrace();
}

在活动结束时

switch(msg.what) {
    case 123:
        if(msg.obj != null) {
            Bundle bundle = (Bundle) msg.obj;
            System.out.println("Got integer "+ bundle.getInt("key"));
        }
    break;
}
欢呼: - )

答案 1 :(得分:6)

老问题,但我正在回答,这可能会对将来有所帮助。

如果您使用的是实际对象,请务必执行Parcelable Android: How to implement Parcelable to my objects?

然而,由于OP表示他尝试使用Primitives并且它不起作用,这就是该怎么做。

问题在于msg.obj=1;这需要一个实现Parcelable

的实际对象

使用msg.arg1 = 1;

然后,您可以使用msg.arg1

在服务端检索参数

为简单起见,我使用(直接来自我的代码)

Message msg = Message.obtain(null, PlayerService.MSG_ACTION_SEEK, i, -1);

-1对我来说只是一个持有人。

希望这有帮助。

修改

小心

Message msg = Message.obtain(null, PlayerService.MSG_ACTION_SEEK, i);

这个签名相当于OP的第一次尝试,并期望一个Parcelable,实际上是让我绊倒并让我首先搜索。它不会在运行时之前抛出错误。

答案 2 :(得分:0)

除了原始数据之外,您在“活动”和“服务”之间徘徊的对象需要实现Parcelable,最好是Serializable。

我希望这有帮助,

最佳

-serkan

答案 3 :(得分:0)

您必须使用Bundle传递传统类型数据,否则会出错:

Java.lang.RuntimeException:跨编组进程不能使用非Parcelable对象。

由于Binder事务数据称为Parcel,因此必须实现Parcelable接口,否则无法在两个应用程序之间进行通信。之所以传递Bundle是因为该类实现了Parcelable接口。当然,如果要传递类,还必须实现接口。

你可以写下来:

Message msg = Message.obtain(null, 1);
msg.getData().putInt("key",1);
msg.replyTo=new Messenger(new PlanRequestIncomingHandler());
try {
    msgService.send(msg);
} catch (RemoteException e) {
    Log.i(tag, "Can not send msg to service");
    e.printStackTrace();
}
抱歉,我的英语非常糟糕

答案 4 :(得分:0)

我已经为Android实现了Actor Model(如Akka),因为Akka需要Java 8,我使用RxJava2为Android制作了自己的实现,它很容易实现......一旦它在那里,你可以将包含任何对象的消息发送到任何接收者(活动,片段,服务,Pojo等),而无需担心线程或序列化

如果你不知道什么是Actor Model,很难解释我自己的实现,但如果你这样做,你可以创建一个名为" Actor"用一种方法

declare
  LOG_REFERENCE xmltype:=xmltype('<log  />');
begin

  select  XMLQuery('
    copy $p := $p1 modify(
     insert node <update data="{$p2}" />
              as last into $p/log
    )

    copy $i := $p modify(
      if (fn:exists($i/log[1]/@t)) then (
        replace value of node $i/log[1]/@t with $p2
      ) else (
        insert node attribute  t {$p2} into $i/log[1]
      )
    )

    return $i
    ' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT)
      INTO LOG_REFERENCE from dual;

  dbms_output.PUT_LINE(LOG_REFERENCE.getClobVal());
end;

您可以通过任何Actor实现此接口,并注册任何Actor,您可以创建一个具有方法的ActorSystem类:

void onMessageReceived(Message message);

当您注册演员(活动或服务)时,您可以通过以下方式决定接收消息的线程/日程安排程序:

static void register(Actor actor, PublishSubject<Message>  mailbox); 
static void unregister(Actor actor);
static void send(Message message, Class<? extends Actor> ... actors);

你在onCreate()中注册你的Actor,在onDestroy()中注册unRegister

或者如果你想要一个库(但我没有测试它),你可以看看这个:

https://github.com/actorapp/droidkit-actors