I'm exploring Google's Android Architecture Components. In my project I'm relying on Services and IntentServices. What is the correct way to communicate with app's ViewModel from an IntentService or Service? Is it achievable using LiveData?
TL;DR It's achievable - use an observer relationship. Your IntentService and likely location service should not be aware of your ViewModel. Consider using a Repository. LiveData can be used (see postValue
). It's good for updating the UI (ViewModel to Activity communication) because it's lifecycle-aware. When you're not updating the UI, you could consider RxJava.
It depends on what architecture you're following. If you're doing something similar to what's described in the Guide to App Architecture, your IntentService is probably started by your remote data source code:
Your remote data source code would have an observable (Rx Flowable, LiveData, etc) which I'll call observable A, for the data downloaded by your intent service. You Repository class (if you use one) would have an observable b and your ViewModel would have an observable c.
The Repository subscribes to the observable in your networking code (observable A), the ViewModel subscribes to the observable in your Repository (observable B), and your Activity/Fragment/View subscribes to the observable in your ViewModel (observable c). Then...
It's basically a long chain of observer relationships all the way up. At each level, the appropriate processing is done, then it sets an observable, which triggers the next level with the new data. This allows you to avoid strong coupling with your IntentService/Repository/ViewModel.
Your Services would not be aware of your ViewModel (or Repository if you have one), they should simply set the value of an observable. If you want to skip having a repository, you could have the ViewModel observe your remote data source class, but if you need to do any logic like saving the data you downloaded to a database, you probably want a Repository.
Two notes about LiveData
- If you need to update LiveData when you're doing a background operation, use postValue
.
LiveData is lifecycle-aware, which makes it particularly well suited for observation by things with lifecycles (Activities/Fragments). The observe
method takes a LifecycleOwner
.
For observers like B and A in your Repository/Networking code, there likely won't be a LifecycleOwner. This means either doing something like using observerForever
, or using another observable, like an RxFlowable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With