I have 3 components the need to talk to each other:
Activity <---> Service <---> Notification
^ ^
| |
----------------------------------
The notification is started from the service and it needs to have custom view with buttons. Clicking on any of the button should send something to the activity and the service.
What is the best way of implementing this?
The options that I see:
Broadcast Receivers
Event bus
Eventbus is definitely not a consideration for interaction here. The Eventbus will only function within the same process in which it's created. That means it's maybe possible to communicate with your Service from your activity with Eventbus, but only if the service is a part of the Activity's process, which generally they shouldn't be (that's what threads are for). So I would strongly advise against that. And notifications are definitely not in the scope of the Eventbus.
You must use Android's documented infrastructure for the interactions you require.
From the Eventbus frontpage:
performs well with Activities, Fragments, and background threads
Broadcast receivers and intents are the best place to start with communications between the components you are using. Check out the answer to this question on how to use the Broadcast Receiver in your fragment to receive intents from a service.
You can also look into Service Binding if you need to have some tighter communication between your service and activity, but again, try to avoid that if you can because it can get very complicated very quickly.
For notifications, it really depends how complicated they are, but start with just building a Notification locally and you will start to understand what you can do with them. You'll notice that they also heavily make use of Intents.
Finally, read this article I wrote about (one) correct use of the EventBus.
Event bus best solution to interaction with components
Related
This is a follow up from this post
How to use GreenRobot's EventBus in broadcasting events from Service to Activity?
my use case revolves around a service and an Activity.
Service is used for tracking the changes in the BLE connection.
Activity is used for reporting that connection state to the UI.
Existing scenario. Service is using broadcast for sending the events (via sendBroadcast() method) of each state revolving around BLE
(connected/Disconnected, Data available, etc..)
My Doubt: Can I make use of this GreenRobot's EventBus Library to control (send and receive events) in same way as broadcast does? If so, Is there anything I should consider (about thread safety) or to be must known, while replacing the broadcast control (send and receive) paradigm completely.
I'm currently using Otto (very similar to EventBus) to accomplish what you're wanting to do.
I have a service which holds a timer, and shows a persistent notification. Each update of the notification also publishes the newest information for the Activity to receive and then update the UI.
It's ALOT easier to implement with Otto (and possibly also EventBus, i haven't used that particular library) as i needed to send 4 pieces of information each time i published some information, and it grew tiresome to add extras to intents each time with the regular sendBroadcast() system.
I haven't had any issues after switching to Otto, and it helped me clean up alot of my code.
One thing to note (with Otto atleast) is that it's setup by default to only allow publishing/subscribing on the main thread, and as you're using a service, you'll have to edit this. I'm not sure whether or not EventBus has the same, but look out for it in their 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!
In Android, given a specific Service, how many methods exist for that Service to communicate with other components (activity, content provider, receiver, other services)?
As far as I know, there are at least 7 methods:
startService
AIDL/bindService
sendBroadcast
startActivity
notification
messenger mechanism
Ashmem
Are there any others?
Thanks.
Like gunar said, you can also use an Event Bus.
The most popular are:
Otto (square)
EventBus (greenrobot)
The documentation it's self explanatory but if you need help to get started let me know.
Regards,
Ryan
If you want to classify them, then I would do it as following.
Communication using Intents
Broadcast intents (global and local)
Component intents (start activity, start service)
System notifications
Interprocess communication (IPC), can be used for in-process too.
Bound services
Using Messenger
Communication via shared objects.
Using Singleton (e.g. application or other singleton classes)
Using event bus (EventBus, TinyBus, Otto)
I understand how to use Intents to communicate with the system/other apps. I understand how to use Intents within the same App. I also understand how to use Otto to communicate within the same App.
What are the Pro/Cons of using Otto vs. Intents to communicate between my Activities/Services?
Pros for using Otto:
You get to design your own event types, versus having to use custom actions or something to distinguish one Intent from another
Everything is within your own process (contrast with startActivity() and kin, which always involve IPC, even if the activity you are starting is in your own app), for speed and security
A bit less coding, as you aren't having to instantiate IntentFilter or BroadcastReceiver objects
It offers the producer pattern (as a quasi-replacement for sticky broadcasts)
Being not part of the OS, it has the potential to be updated more frequently
Cons for using Otto:
It cannot start an activity
It cannot start a service
It cannot bind to a service
It cannot send a broadcast
It cannot be used in a PendingIntent or for any true IPC
IOW, the true comparison for Otto is with LocalBroadcastManager, not with the general use of Intents.
I started with a standard local android service, and used Binders with Listeners to communicate. Then: I began noticing some serious issues with handling orientation changes, so I decided to skip the whole binder thing, and just go with broadcasting intents (and using startService exclusively) that contain all the data/commands that need to be passed.
My question is: what are some of the pitfalls I have to look out for when using this approach?
Are there any disadvantages?
If you are supporting API Level 4 and above, use setPackage() to make your "broadcast" be a "narrowcast" -- keeping the broadcast within your app. By default, the broadcast is truly broadcast, to all apps, which may or may not be a good thing for your data.
Don't forget to unregister your BroadcastReceiver (i.e., don't register it and forget it). At the same time, you will need to consider what to do if the service wraps up and the activity is long gone (e.g., BACK button). One approach is to use an ordered broadcast with a low-priority manifest-registered receiver that will raise a Notification if no activity handles the broadcast -- this sample app demonstrates what I mean.
You might consider a Messenger instead of the broadcast approach, as it is intrinsically a "narrowcast", probably is a smidge less overhead, and can't be leaked. I am still working through the mechanics of using this with configuration changes, though.