Calling method in a service?

Put your problem here if it does not fit any of the other categories.

Calling method in a service?

Postby Spoogle » Sun Dec 16, 2007 8:41 pm

I've been looking through the tutorials for mention of binding to services, but haven't really found any - did I miss one? :shock:

Google has an example, but it doesn't really mention what to do once you bind. My objective is to bind to a service, pass it a Bundle to work on, then receive a response Bundle once its done (something like having a child thread, but as a single service used by all for synchronization reasons).

I can make the service and bind to it, but when it comes to passing it a bundle (and, on the Service's side, passing anything back), I'm stuck. I get the feeling it's got something to do with overriding the onTransact method in the IBinder, but Google's documentation on that isn't very helpful.

Any thoughts?
Spoogle
Freshman
Freshman
 
Posts: 5
Joined: Mon Nov 26, 2007 3:50 pm

Top

Postby Spoogle » Mon Dec 17, 2007 4:33 am

So the real issue, upon further inspection, is that I'm not sure how the controller/caller gets the IBinder to the service.

In all services there's a getBinder() method, from which you can get a (user-defined) IBinder object. Once you have that object, you can presumably customize it to communicate how you want with the Service.

Anyone know how to call getBinder() to a specific service (bindService just returns a boolean)?
Spoogle
Freshman
Freshman
 
Posts: 5
Joined: Mon Nov 26, 2007 3:50 pm

Postby Spoogle » Tue Dec 18, 2007 4:15 pm

With the help of some folks on the Beginner's discussion group, I got it figured out.

Basically, the best way to send/receive data between a local service and an activity is to use the transact() method. You can call it on the IBinder object, which is given to you in the onServiceConnected() method of your ServiceConnection object (confused yet?). The parameters to pass to it are mentioned in the docs.

Note, however, that bindService() is asynchronous - it gets called 'sometime', and execution of your code (including transact(), if it's after a bindService() call) continues whether or not the service has been bound yet. So the best way to do transact() calls that I've found is to put them in a separate (i.e., serviceTransaction()) method, which is called from the onServiceConnected method of the ServiceConnection object - that way you don't get a NullPointerException when you try to call transact() on an IBinder that doesn't exist, because the service hasn't yet been bound.

All that's well and good, but there's one more critical piece to this:

To get a service to properly return something (via the reply Parcel you gave it in the original transact() call), you need to go into the Service's class and fill out the onTransact() method in your overridden IBinder object (in the demos it's something like mBinder), so that it updates that reply parcel with results before returning it.


I will try to post some sample code for folks within the next few days, but it's going to be hectic - I'll get it up as soon as I can.


If you're looking for getting data to/from a remote service, this tutorial goes very in-depth on the subject. Good luck!
Spoogle
Freshman
Freshman
 
Posts: 5
Joined: Mon Nov 26, 2007 3:50 pm

Top

Return to Other Coding-Problems

Who is online

Users browsing this forum: No registered users and 24 guests