Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
431 views
in Technique[技术] by (71.8m points)

mvvm - Android Architecture Components ViewModel - communication with Service/IntentService

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

enter image description here

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...

  1. IntentService gets data back and sets observable A
  2. This triggers your Repository because it's subscribed - it does the type of data processing the repository is supposed to do, like saving the data to a database.
  3. When your repository is done, it sets observable B with the newly processed data.
  4. This triggers your ViewModel because it's subscribed - it does the type of data processing ViewModels do, namely formatting the data so that it's ready for the view, then sets observable C...
  5. This triggers your Activity/Fragment/View which updates the UI

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...