简体   繁体   English

将 Object 从 Service 发送到 Activity(无法编组非 Parcelable)

[英]Send Object from Service to Activity (Can't marshal non-Parcelable)

I'm trying to send data from my activity to a service and receive some information back, but i'm getting:我正在尝试将数据从我的活动发送到服务并接收一些信息,但我得到:

java.lang.RuntimeException: Can't marshal non-Parcelable objects across processes. java.lang.RuntimeException:无法跨进程编组非 Parcelable 对象。

The code from activity looks like this:来自活动的代码如下所示:

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();
    }

When I set msg.obj = something I get java.lang.RuntimeException, can somebody help me?当我设置msg.obj = something我得到 java.lang.RuntimeException,有人可以帮助我吗?

You can pass Parcelable type objects via Messenger.您可以通过 Messenger 传递Parcelable类型的对象。 Or else if you want to pass primitive data types use Bundle wrapper as below.或者,如果您想传递 原始数据类型,请使用Bundle包装器,如下所示。

In Service End:在服务端:

//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();
}

In Activity End:在活动结束时:

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

cheers:-)干杯:-)

Old question, but I am answering so it might help someone in the future.老问题,但我正在回答,所以它可能会在未来帮助某人。

If you are using actual objects, then by all means, please implement Parcelable Android: How to implement Parcelable to my objects?如果您使用的是实际对象,那么请务必实现Parcelable Android:如何对我的对象实现 Parcelable?

However, as the OP stated that he tried using Primitives and it did not work, this is what to do.但是,正如 OP 所说,他尝试使用 Primitives 并且它不起作用,这就是要做什么。

The problem lies here msg.obj=1;问题出在这里msg.obj=1; This expects an actual object that implements Parcelable这需要一个实现 Parcelable 的实际 object

Use msg.arg1 = 1;使用msg.arg1 = 1;

you can then retrieve the argument on the service side using msg.arg1然后,您可以使用msg.arg1在服务端检索参数

For simplicity I use (straight from my code)为简单起见,我使用(直接来自我的代码)

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

The -1 is just a holder for me. -1 对我来说只是一个持有者。

Hope this helps.希望这可以帮助。

Edit : Be careful with编辑:小心

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

This signature is equivalent to the OP's first attempt and expects a Parcelable and is what actually tripped me and got me searching in the first place.此签名等效于 OP 的第一次尝试,并且需要 Parcelable 并且实际上是让我绊倒并让我首先进行搜索的原因。 It won't throw an error until runtime.直到运行时它才会抛出错误。

You must use the Bundle to pass the conventional type data, otherwise it will be wrong:必须使用Bundle传递常规类型数据,否则会报错:

Java.lang.RuntimeException: Can't non-Parcelable objects across marshal processes. Java.lang.RuntimeException:不能跨编组进程的非 Parcelable 对象。

Because the Binder transaction data is called Parcel, the Parcelable interface must be implemented, otherwise it is not possible to communicate between the two applications.因为Binder交易数据被称为Parcel,所以必须实现Parcelable接口,否则两个应用程序之间无法通信。 The reason why Bundle is passed because the class implements the Parcelable interface.之所以通过Bundle是因为class实现了Parcelable接口。 Of course, if you want to pass the class must also implement the interface.当然,如果要通过class也必须实现接口。

you can write like down:你可以这样写:

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();
}

sorry,my english is very bad抱歉,我的英语很不好

I have implemented Actor Model (like Akka) for Android, since Akka requires Java 8, i made my own implementation for it for Android, using RxJava2, it was very easy to implement... And once it is there, you can send messages holding any object to any receiver (Activity, Fragment, Service, Pojo, etc.) without worrying about threads or serialization I have implemented Actor Model (like Akka) for Android, since Akka requires Java 8, i made my own implementation for it for Android, using RxJava2, it was very easy to implement... And once it is there, you can send messages将任何 object 保存到任何接收器(活动、片段、服务、Pojo 等),而不用担心线程或序列化

It is hard to explain my own implementation in details if you dont know what is Actor Model, but if you do, you can make an interface named "Actor" with one method如果你不知道什么是 Actor Model,很难详细解释我自己的实现,但如果你知道,你可以用一种方法制作一个名为“Actor”的接口

void onMessageReceived(Message message);

And you can implement this interface by any Actor you have, and to register any Actor, you can create an ActorSystem class that has methods:您可以通过您拥有的任何 Actor 实现此接口,并且要注册任何 Actor,您可以创建一个具有以下方法的 ActorSystem class:

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

And when you register your Actor (Activity or Service), you decide what is your thread / scheduler to receive your messages on, through:当您注册您的 Actor(活动或服务)时,您可以通过以下方式决定接收消息的线程/调度程序是什么:

PublishSubject.observeOn(Schedulers.trampoline());

And you register your Actor in onCreate() and unRegister in onDestroy()你在 onCreate() 中注册你的 Actor 并在 onDestroy() 中取消注册

Or if you want a library for that (but i did not test it), you can take a look at this:或者如果你想要一个库(但我没有测试它),你可以看看这个:

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

Other than primitive data, the objects you're juggling between Activities and Services need to implement Parcelable and preferably Serializable.除了原始数据之外,您在活动和服务之间玩弄的对象需要实现 Parcelable 并且最好是 Serializable。

I hope this helps,我希望这有帮助,

Best最好的

-serkan -serkan

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 intent.putExtras(String key,Message object)引发无法跨进程封送不可Parcelable对象 - intent.putExtras(String key, Message object) throws Can't marshal non-Parcelable objects across processes 保存和还原哑小部件的不可拆分UI状态 - Saving and restoring non-Parcelable UI state for a dumb widget 将JSON解析为Parcelable对象,以将Parcelable对象发送到Android中的另一个Activity - Parsing JSON to Parcelable objects to send Parcelable object to another Activity in Android Android可打包对象传递给活动,但不传递给服务 - Android parcelable object passes to activity but not to service Android:可打包对象已成功传递给另一个活动,但现在我无法使用其任何方法 - Android: Parcelable object successfully passed to another activity, but now I can't use any of its methods 将实现Parcelable的对象从一个活动传递到另一个活动 - Pass Object implementing Parcelable from one Activity to Another Activity 如何使用parcelable在活动之间传递线程类对象 - how to pass a thread class object from activity to activity using parcelable 尝试访问从一种活动发送到另一种活动的可包裹对象 - Trying to access my parcelable object sent from one activity to another 无法从服务中调用主Activity - Can't call main Activity from service 将对象列表从Web服务发送到另一个活动 - Send list of object from a web service to another activity
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM