【问题标题】:Send Object from Service to Activity (Can't marshal non-Parcelable)将对象从服务发送到活动(无法编组非 Parcelable)
【发布时间】:2011-09-29 14:11:32
【问题描述】:

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

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,有人可以帮助我吗?

【问题讨论】:

    标签: java android runtimeexception


    【解决方案1】:

    您可以通过 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;
    }
    

    干杯:-)

    【讨论】:

    • 代码示例不完整!!! switch 写在哪里了?
    【解决方案2】:

    老问题,但我正在回答,以便将来可能对某人有所帮助。

    如果您使用的是实际对象,那么请务必实现 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,这实际上是让我绊倒并让我首先搜索的原因。直到运行时才会抛出错误。

    【讨论】:

      【解决方案3】:

      除了原始数据之外,您在活动和服务之间玩转的对象需要实现 Parcelable 并且最好是 Serializable。

      希望对你有帮助,

      最好的

      -serkan

      【讨论】:

      • 我有 msg.obj=1 所以它的值是一个原始的并且它不起作用,我尝试了一个实现 Serializable 的自定义对象并且我得到了同样的错误。我认为@CommonsWare 是对的。我会尝试该解决方案并通知您...
      • 当然,请随时通知我们,谢谢乔治,我很感激。
      【解决方案4】:

      必须使用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();
      }
      

      对不起,我的英语很糟糕

      【讨论】:

        【解决方案5】:

        我已经为 Android 实现了 Actor 模型(如 Akka),因为 Akka 需要 Java 8,所以我为 Android 做了自己的实现,使用 RxJava2,它很容易实现......一旦它在那里,你可以将持有任何对象的消息发送到任何接收者(Activity、Fragment、Service、Pojo 等),而无需担心线程或序列化

        如果你不知道什么是Actor Model,我很难详细解释我自己的实现,但是如果你知道,你可以用一种方法制作一个名为“Actor”的接口

        void onMessageReceived(Message message);
        

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

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

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

        PublishSubject.observeOn(Schedulers.trampoline());
        

        然后你在 onCreate() 中注册你的 Actor 并在 onDestroy() 中取消注册

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

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

        【讨论】:

          猜你喜欢
          • 2019-10-12
          • 1970-01-01
          • 2012-04-04
          • 2017-12-24
          • 1970-01-01
          • 2012-10-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多