12

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

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

4

5 回答 5

17

您可以通过 Messenger传递Parcelable类型的对象。或者,如果您想传递原始数据类型,请使用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;
}

干杯:-)

于 2015-01-29T17:33:42.227 回答
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 并且实际上是让我绊倒并让我首先进行搜索的原因。直到运行时它才会抛出错误。

于 2014-06-28T20:15:32.727 回答
0

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

我希望这有帮助,

最好的

-serkan

于 2011-07-07T03:24:41.380 回答
0

我已经为 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

于 2017-06-19T20:05:16.727 回答
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();
}

抱歉,我的英语很不好

于 2017-02-14T07:31:14.560 回答