我的服务设置为在单独的流程中启动:
<service android:name=".services.UploadService"
android:process=":UploadServiceProcess" />
我可以使用bindService()成功绑定到它。当我尝试通过调用Messenger.send()发送消息时出现问题:
service.send(Message.obtain(null, UploadService.MESSAGE_UPLOAD_REQUEST, uploadRequest));
其中uploadRequest是实现Parcelable的自定义对象
public class UploadRequest implements Parcelable { public File file; public boolean deleteOnUpload;
public UploadRequest(File file, boolean deleteOnUpload) { this.file = file; this.deleteOnUpload = deleteOnUpload; } private UploadRequest(Parcel in) { this.file = new File(in.readString()); } public int describeContents() { return 0; } public void writeToParcel(Parcel dest, int flags) { dest.writeString(this.file.getPath()); } public static final Parcelable.Creator<UploadRequest> CREATOR = new Parcelable.Creator<UploadRequest>() { public UploadRequest createFromParcel(Parcel in) { return new UploadRequest(in); } public UploadRequest[] newArray(int size) { return new UploadRequest[size]; } };
public UploadRequest(File file, boolean deleteOnUpload) { this.file = file; this.deleteOnUpload = deleteOnUpload; } private UploadRequest(Parcel in) { this.file = new File(in.readString()); } public int describeContents() { return 0; } public void writeToParcel(Parcel dest, int flags) { dest.writeString(this.file.getPath()); } public static final Parcelable.Creator<UploadRequest> CREATOR = new Parcelable.Creator<UploadRequest>() { public UploadRequest createFromParcel(Parcel in) { return new UploadRequest(in); } public UploadRequest[] newArray(int size) { return new UploadRequest[size]; } };
我在我的服务handleMessage中设置了一个断点,但我的应用程序永远不会到达断点。但是,如果不是使用我的自定义UploadRequest对象而是发送null,我会像我期望的那样到达handleMessage断点,但显然我不能做任何事情。我在调用writeToParcel时返回非null String验证了file.getPath()。这让我相信我的UploadRequest课程中有些东西已经关闭,但是通过谷歌搜索,我看不出我的班级有什么问题。有什么想法吗?
答案 0 :(得分:13)
Message member obj的文档说:
要发送给的任意对象 接受者。使用Messenger时 在此过程中发送消息 如果它包含a,则只能为非null 可分解框架类(不是 一个由应用程序实现)。 用于其他数据传输使用 使用setData(束)。注意Parcelable 此处的对象以前不受支持 到FROYO发布。
我的猜测是你看到了一个问题,因为你正在创建自己的parcelable,这在穿越过程边界时是不允许的。相反,您必须将对象打包成一个包。这也意味着您的对象需要实现Serializable,但不需要是Parcelable。
答案 1 :(得分:3)
刚刚尝试过这个。
Message.obj可以传输框架类,例如ContentValues。
和Message.SetData可以跨进程传输一个Bundle,你可以将任何Parcelable对象放入bundle中。
当收到Messag时,记得在bundle上调用setClassLoader。
发送方
Message localMsg = Message.obtain();
localMsg.what = TPServiceConnection.MSG_REPLY_SERVICE_HELLO;
Bundle data = new Bundle();
ContentValues cv = new ContentValues();
cv.put("KEY", mRand.nextInt());
data.putParcelable("KEY", cv);
TPServiceDataModal modal = new TPServiceDataModal(mRand.nextInt());
data.putParcelable("KEY2", modal);
localMsg.setData(data);
接收方
Bundle data = msg.getData();
data.setClassLoader(this.getClass().getClassLoader());
Parcelable parcelable = data.getParcelable("KEY");
if (parcelable instanceof ContentValues) {
ContentValues cv = (ContentValues) parcelable;
Log.d(TAG, "reply content: " + cv.getAsInteger("KEY"));
}
Parcelable parcelable2 = data.getParcelable("KEY2");
if (parcelable2 instanceof TPServiceDataModal) {
TPServiceDataModal modal = (TPServiceDataModal) parcelable2;
Log.d(TAG, "reply modal: " + modal.mData);
}
其中TPServiceDataModal是Parcelable calss。
答案 2 :(得分:0)
通过Bundle
传递parcelable对象的例子,记得使用classLoader
并用正确的包定义对象
val msg: Message = Message.obtain(null, MSG_SAY_HELLO)
msg.data = Bundle().apply {
putParcelable("KEY_MY_OBJECT", MyObject("an", 12))
}
mService?.send(msg)
.
package com.example.androidmessengerclient
@Parcelize
class MyObject(val name: String, val age: Int) : Parcelable
override fun handleMessage(msg: Message) {
when (msg.what) {
123 -> {
msg.data.classLoader = MyObject::class.java.classLoader
val o = msg.data.getParcelable<MyObject>("KEY_MY_OBJECT")
}
}
}
。 Server
应用中的模型需要具有与 Client
应用
package com.example.androidmessengerclient
@Parcelize
class MyObject(val name: String, val age: Int) : Parcelable