I have a situation which I will try to explain clearly. I have two services, Service A and Service B.
Activity C connects to service A using onBind(). Service A connectes to Service B using a callback object. I want Service A's onbind to not be executed until Service B is connected to Service A. What will be a good way to achieve this?
The right answer is: combine the two services into one.
The next-best answer is: redesign your app such that A is not binding to B, or that C does not care whether A is bound to B.
You can't delay the call from the onBind. If your service's interaction is such that it may not be ready for use until later, you could have a method on the interface returned by onBind that allows a client to get a callback when it is ready. (You could even have this set up where the main interface is just "getRealInterface" that takes a callback, which is given the real interface for your service once you are ready to give it.)
Related
I am developping a MusicPlayer app, and I use a local Service to be make the MediaPlayer run in the background. It seems that we can either send intent to start a Service or bind a Service. I understand the point of for startService, we leave it running and send intent to stopService, and for bindService, we get back a IBinder to communicate with the service. However, I'm wondering what's the point of doing this? Do we have to send intents to make it work?
If I just retrieve an static instance of Service, and directly call its methods, I can also implement both start it and communicate with it.
I found an example of not using startService nor bindService, but it works well as a simple MusicPlayer.
The fragment calls Service:
https://github.com/zacharytamas/spotify-sampler/blob/master/app/src/main/java/com/zacharytamas/spotifysampler/ui/PlayerFragment.java
The Service class:
https://github.com/zacharytamas/spotify-sampler/blob/master/app/src/main/java/com/zacharytamas/spotifysampler/services/PlayerService.java
However, I'm wondering what's the point of doing this?
To have the service be running, to tell the OS "hey, we are doing work here on behalf of the user, please let my process live a bit longer".
This is covered in the documentation.
Do we have to send intents to make it work?
Yes.
If I just retrieve an static instance of Service, and directly call its methods, I can also implement both start it and communicate with it.
Then it is merely a Java object, and there is no point in inheriting from Service. Also, it means that your process will live for less time when your UI is not in the foreground.
I found an example of not using startService nor bindService, but it works well as a simple MusicPlayer.
The service is started, via startService(), in ArtistSearchActivity. Until this is done, the service does not exist, and the singleton will be null.
startService is used when you don't need to communicate with the service.
BindService is used when yout need to communicate with it.
In your app, I think you will communicate with the service (for example, if you have an activity where you choose the song, your will send data to the service to say: "this is the song which you have to play now") and I think you will need BindService instead startService.
I hope this will help you :D
I have two problems:
I know that for connection activity and remote-service I have to use AIDL.
I tried this and it's work but I can find only one way connections example. In simple words - reading something from service (by activity). But I need solve for sending some data to activity (by or from service). It's so important because the service have to send some information to activity immediatly after some its events (obtain data from the net).
Is it way to bring to front again closed application (activity) from the remote service?
Any suggestions would be greatly appreciated.
Regards
Artik
It's so important because the service have to send some information to activity immediatly after some its events (obtain data from the net).
You can use AIDL for two-way communication. You would need to expose not only the service interface, but a callback interface, via AIDL, with the client having the .Stub of the callback and supplying an instance of it in a parameter to a method on the service interface. This gets a bit complex -- here are a pair of sample apps from my book that demonstrate the technique:
Service
Client
Is it way to bring to front again closed application (activity) from the remote service?
Your service can call startActivity(), but generally that is a bad idea. The user may be in the middle of doing something else, when all of a sudden your activity pops into the foreground. Occasionally, the user may deem your activity to be more important, but not always. Consider using a Notification instead, to let the user know that there is something in your app that needs the user's attention.
First, create a private resultreceiver variable in your service. Then create a method to set this resultreceiver via a connected activity. Then use AIDL to pass on a resultreceiver to the running service from the activity via the method you just made. Then in the service use resultreceiver.send if the resultreceiver is not null.
A few examples to get you started
http://lalit3686.blogspot.com/2012/06/how-to-update-activity-from-service.html?m=1
http://chrisrisner.com/31-Days-of-Android--Day-28–Intents-Part-3--Service-Intents
I have two services A and B. If we want to access some methods of service B in service A we have to create a ServiceConnection class and inside service A we have to create Stub and implements the methods.
But I also want to access the methods of service A from service B. For trial I created one more aidl connection and implemented ServiceConnection it works fine, is it the only way OR we can use the existing serviceconnection and implement this functionality by other way?
I would assume this is the only way AIDL works from my experience. You could always create a custom callback that could be passed into service B from service A, then when B would like to send back to A it could trigger the callback. There is also the option of passing intents back and forth or communication through a socket. Just make sure you are blocking on the other side.
Services can certainly have callback interfaces (i.e. so services can call methods in clients).
Suggest you refer to the RemoteService example in the SDK.
I'm developing an app with a service that forwards calls to a web-service, and a few activities that place those calls. The activities need to process the results of those calls. For example, I have a writeComment method on the service, that accesses the web-service and returns some information about the newly written comment.
Right now I let the Activity take care of all the threading. The Activity binds the service, and then uses an AsyncTask that calls the bound service's writeComment method.
All works well as long as the Activity isn't stopped while the AsyncTask is running. If it does (easily happens when flipping the phone), the AsyncTask dies a violent death when trying to update the UI in onPostExecute. I'm not entirely sure how to fix this - I do need to let the user know the server has been updated.
If I go the other way around, and register a callback with the Service, I'm still a bit stump, because I need to notify the Service the Activity has changed - I need to tell it not to notify me in the first Activity's onDestory, and reregister in the second Activity's onCreate. And I need to handle the case where the asynchronous task completes after onDestroy and before onCreate.
What is considered Best Practice in this case?
Thanks,
Itay.
My intuition tells me to let the service handle the threading. Services are far less transient (although still transient to some degree) than activities and therefore you'll have less issues of threads trying to interact with a Context (be it an Activity or a Service) that's no longer there. Have you looked at the IntentService class? It handles a lot of the threading for you.
In my app, I have a long-running service and Activities that need to render data in the service. The service also pings the Activities when there is a change but the Activity can also query the service. The way I approached this was two-fold.
Firstly, I bind my activity to the Service in order to send messages from Activity to service.
Secondly, the Service sends notifications with Broadcasts and the Activity listens for those broadcasts. I set that up in the Activity onResume and tear it down in the onPause. I think this is the part that you're missing.
I am currently writing an app, which consists of a service and an activity. The service is running in the background, doing some live audio processing. If the user want to get some information about the running service or want to change the settings of the service, the activity gets started and bind to the service.
Currently i am using the asynchronous messenger system to communicate between the service and the activity. For example, the service can send some results to the activity through a message and the activity can handle this message and show the results. This works fine, but it is stressful to write the messaging stuff for each communication. And it is not always needed. Sometimes i only want to ask the service, if a flag is set or not. If i do this asynchronous, i have to send a message to the service which asks for the value of the flag and the service has then to send a message back to the activity to answer the request.
So i want to have some getter and setter which can synchronously access the service. This can be done by using a binder, which works too.
The problem is, that i sometimes need synchronous communication to get the value of flags etc. and sometimes i need asynchronous communication to push the results from the service to the activity. So what i need is a binder and a messenger. But i dont know how this can be done, because the service can only return one object from the onBind() method, either a binder object or a messenger object.
Do you have any suggestions how this can be done or some other approach to realise asynchronous and synchronous communication between an activity and a service?
Thanks in advance!
Tobias
If you are already binding to the service, your activity can supply a listener object to the service, which the service will then call when events occur.
You just need to make sure that you unregister that listener object before unbinding from the service, and do both before the activity is destroyed, so your service does not wind up with a strong reference to a defunct activity.