I would like to ask for some example, where two different activities (a button in the first activity opens a second activity), are communicating with one service (AIDL, etc.).
I've tried many different tutorials, but they are only about how to make one activity → one service.
This is probably old, but I'll try to answer it anyway...
In Android, seeing as only one Activity can bind to a Service at a time, and only one Activity can be shown at a time, there isn't any real reason to want to bind two Activities at a time.
But, if you'd like, the best solution is to bind the Service in the onResume() method, and unbind it in the onPause() method. This allows you to give two unrelated Activities access to the service, while only having one bound at a time.
Each Activity is responsible for binding and unbinding from the Service. This is normally done in onResume / onPause, or onStart / onStop, depending on your requirements. One Activity cannot bind another Activity to a Service. That's just the way it is. :)
You can do it by using Messenger that provide IPC communication without using AIDL. This is how you can bind multiple activities to a service.
If you need your service to communicate with remote processes, then
you can use a Messenger to provide the interface for your service.
This technique allows you to perform inter-process communication (IPC)
without the need to use AIDL.
Have a look at this link. When you see the code, you will find a switch case within a Handler. This will cater to the multiple requests that you will send from you multiple activities/components.
Related
I have a service, I need to communicate to with it (one service - many fragments/activities). There are two options for this:
Have a singleton that controls the service - starts it and then binds to it (using the app context)
Have a singleton that controls the service - starts it, the service when ready registers back as a delegate to the singleton (in a WeakReference)
Solution no 2 seems simpler to me, but whenever I read about communication with services there is the concept of the bound service.
Is there any benefit of having a bound service instead of the service registering itself as a delegate (and unregistering with onDestroy)?
Edit 1: The service is to keep the communication alive, it's expensive to set up a new communication channel. Even if no one requested any data it should keep the channel alive (heartbeat).
The service is foreground, it should run even if the activity that requested the data gets killed by the system. The next time it is created the data will be there.
The data requested by one screen might be useful for some other (therefore has to be stored in a singleton).
Bound and unbound services are both usable patterns and you should pick whatever pattern is better for you use case.
You should pick bound service if you want your service to have the same lifecycle as the components that bind to it. If you need an independent service use an unbound version.
The only benefit of one approach versus another is the simplicity of implementation.
In you case, I think you need the service only while there are running activities and fragments, then the easiest way, in my opinion, would be to make a bound service and make every activity bind to it. With that, you'll get a simple communication interface between you activities (and fragments, since they have access to containing activity) and your service.
The benefits of this approach are:
the service will stop itself if all activities unbind and start itself when first activity binds to it.
you won't need to track all running activities in the singleton and manually unbind
you won't need to maintain a singleton manager, less code -> less bugs
sometimes onDestroy can be skipped by the system and you can leak the service with the 2 approach.
Since you need your service to be running the correct option will be to use a started service and make each activity bind to it when needed. It's a common pattern.
Started service will run until you explicitly stop it or it stops itself, you can have a singleton manager that will be responsible for that.
But at the same time you can communicate with the service from your activity using binding.
So basically comparing with the first suggested approach, you'll need some instance that will start and stop the service, but the communication between activities and service will be the same - using binding.
Yes, using a bound service in Android is a much better option when communicating with Views like Activities/Fragments. This is because of the following reasons,
It runs synchronously.
You can have more control on the service data when to show on UI thread of the view. You can choose when to call it in async/sync way.
LocalBroadcastManager only runs Asynchronously.
i'm having trouble finding a way to implement this:
I have an activity A from where i'll start 2x separate socket connections.
Afterwards i'll move to an activity B from where i'll go back and fourth with activities C and D. All 3 activities will exchange messages via the sockets.
Now from my understanding i need to create a service for each socket, but how exactly do i maintain both sockets open, without creating a new connection everytime i switch to another activity?
Also how do i keep the services running an "accept loop", prompting an action for the current activity the user is in?
thanks
You're correct that you should use a Service. A good rule of thumb is that you should use a service for any background processing that is not logically bound by the lifecycle of a single activity. (And use AsyncTask for background processing that is logically bound by the lifecycle of a single activity.)
But you don't need to create a service for each socket. You should create one service that does whatever it is you need to do with the sockets. There are a variety of ways your activities can interact with the service and pass messages or obtain references to its sockets, which you can read about in the documentation.
I have a situation where an activity needs to start 2 services, one is bound, one is not.
The bound will return a Ibinder to the activity. But the activity needs to some how provide a callback to both the services, i.e. both services must be able to call some methods in a nested class in the activity.
What is the best way to do this ? Should I use broadcast from services, and then call the desired API from the onReceive() ? Or can I pass a IBinder from my activity to service in the intent, and the service could use it to make a IPC call back ?
Edit
Forgot to clarify .. the two services are in a different app than the activity.
you could to use LocalBroadcastManager Sending An Intent for Activity
I believe it is the best option for this scenario EventBus or Otto
EventBus is an Android optimized publish/subscribe event bus. A
typical use case for Android apps is gluing Activities, Fragments, and
background threads together. Conventional wiring of those elements
often introduces complex and error-prone dependencies and life cycle
issues. With EventBus propagating listeners through all participants
(e.g. background service -> activity -> multiple fragments or helper
classes) becomes deprecated. EventBus decouples event senders and
receivers and thus simplifies communication between app components.
Less code, better quality. And you don't need to implement a single
interface!
I have a series of activities, one of which is called UserActivity. What I'd like to do is have an object ListenerObject, that listens specifically for when UserActivity starts or stops. That is, I want UserActivity.onStart() to call ListenerObject.onActivityStart() (or some method named similarly).
I know that I can create an observer pattern set of classes to do this, but I'm wondering if there already exists such a framework within the Android API, and, more importantly, an accepted set of use patterns.
You could do this through Broadcasts:
http://developer.android.com/reference/android/content/BroadcastReceiver.html
http://developer.android.com/guide/components/intents-filters.html
In a few ways...
1) Have both activities receive and start from the same intent.
2) have activity 1 launch a broadcast to activity 2.
If ListenerObject makes sense as a static singleton you can just call the method on it during onStart() and onStop():
MySingleton.getSharedInstance().onActivityStart();
which would save you some overhead of the other valid methods mentioned.
The Android devs mention static singletons in the context of lazy creation for speed and reduced memory usage quite a bit it seems so it seems like an accepted pattern.
Depends on the required life cycle of the ListenerObject.
Seems like you want it to be around when the UserActivity isn't, but what about when you have none of your Activities on screen?
You could start a Service and then bind / unbind to it in your UserActivity's onStart / onStop. The service would likely stay alive whilst your app was in the background.
You could (un)bind to a service in all your Activities' onStart/Stop and provide an IBinder interface which asks would allow the service to ask the Activity if it is the UserAnctivity. The service would live whilst you navigate the app, but die once you put it in the background or go to another activity that doesn't bind to it (probably not what you want if you're doing something with G+ authentication / in app purchases etc).
You could (like others suggest) create a singleton, which won't die until the Application does, but won't keep it alive either.
You could have an Event Bus where the Listener subscribes to a known event published by the UserActivity.
shrug just some ideas
I want to do Bluetooth connection in Service. And there needs to be interaction between Activities and Services. The service should be started as soon as the app is started and should be able to communicate with UI Activities on certain situations.
What should be the appropriate way of doing it? If I bind the service from only one Activity then that service will be communicating only with that Activity. So, do I need to take AIDL based approach or is there any other way out for this?
Otherwise, can I have a class that extends Application class and then start the service from there and bind the Application class instead?
This is quite a broad question, so I'll answer as best as I can. From what I know of services, multiple activities can bind a single service, all having access to it. Only once all activities that bound the service end their connections (by unbinding), does the service actually stop.
The android documentation on services tells us:
... the system will keep the service running as long as either it is started or there are one or more connections to it with the Context.BIND_AUTO_CREATE flag. Once neither of these situations hold, the service's onDestroy() method is called and the service is effectively terminated
So my recommendation would be to bind the service from all activities that need to communicate with it. When binding with a service an IBinder is returned, which you can use to communicate with the service. Again according to the Android documentation on services:
Usually the IBinder returned is for a complex interface that has been written in aidl.
Although if you only need to perform simple communication with the service, you could use the Messenger class instead of writing full AIDL files. A sample of this can be found here.
Hope this answers your question!
You could bind directly to the Service as the above answer states, however there is no need for Messengers. Your service will be running in the same process as your activity 99.9% of the time. Messengers are designed for inter-process communication (IPC). Also no need for AIDL - that was designed for advanced IPC.
Instead, you should use: BroadcastReceivers and Intents. This is what they were designed for (communication between components in an app).