Passing custom object to android service in different processes

I have a service that starts in a separate process:

<service android:name=".services.UploadService" android:process=":UploadServiceProcess" /> 

And I can successfully bind to it using bindService (). My problem occurs when I try to send a message by calling Messenger.send ():

 service.send(Message.obtain(null, UploadService.MESSAGE_UPLOAD_REQUEST, uploadRequest)); 

where uploadRequest is a custom object that implements 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]; } }; 

} Code>

I set a breakpoint in my handleMessage services, but my application never hits a breakpoint. However, if I send null instead of using my custom UploadRequest object, I get to the handleMessage breakpoint as I expected, but obviously I can’t do anything at this point. I checked the .getPath () file when calling writeToParcel returns a non-empty String. This makes me believe that something is not in my UploadRequest class, but from googling I see nothing wrong with my class. Any ideas?

+7
source share
2 answers

Documentation The obj message participant says:

An arbitrary object to send to the recipient. When using Messenger to send a message through processes, it can only be nonempty if it contains the Source framework class (not one is implemented by the application). For another data transfer, use SetData (Bundle). Please note that Parcelable objects are not supported here before the release of FROYO.

I assume that you see the problem because you create your own argument, which is not allowed when crossing the process boundary. Instead, you have to pack your object in a package. It also means that your object will need to implement Serializable, but not necessarily be arbitrary.

+13
source

tried it now.

Message.obj can pass a framework class, such as ContentValues.

and Message.SetData can pass the packet through processes, and you can put any Parcelable objects in the packet.

just remember to call setClassLoader on the package when Messag is received.

send side

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

take side

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

where TPServiceDataModal is a clerical calss.

+3
source

All Articles