patternjavaMinor
Using a Subject to trigger a music list to reload
Viewed 0 times
triggerreloadsubjectusingmusiclist
Problem
In my Android app I have a Service that is periodically polling a server for a music playlist XML. For certain occasions I also want to trigger a reload manually.
I am using Retrofit for the server communication and my Service exposes an
Now, I want all Subscribers to receive any new playlist info as soon as it becomes available. In particular this means that if I trigger a reload manually from the Fragment, the Service should also immediately receive the server response.
No matter how I turn it, all my solutions need a Subject. Here's the one I like best:
Since, it seems to me, one should generally avoid Subjects and try to use only normal Observables instead my question is: Is there any way to this that does not need Subjects? Is this a case where using Subjects is the way to go?
And also: What are the main drawbacks of Subjects in general?
I am using Retrofit for the server communication and my Service exposes an
Observable to which some other components of the app can subscribe. At the moment there are two such subscribers: One Fragment that contains the playback controls and one other Service that manages the actual audio streaming as well as the updates to the Notifications.Now, I want all Subscribers to receive any new playlist info as soon as it becomes available. In particular this means that if I trigger a reload manually from the Fragment, the Service should also immediately receive the server response.
No matter how I turn it, all my solutions need a Subject. Here's the one I like best:
private Observable mReloadingObservable;
private PublishSubject mManualRefreshesSubject = PublishSubject.create();
private void setupObservable() {
Observable timer = Observable.timer(0, 15, TimeUnit.SECONDS);
Observable pulses = Observable.merge(timer, mManualRefreshesSubject);
mReloadingObservable = pulses
.flatMap(new Func1>() {
@Override
public Observable call(Long aLong) {
Log.d(LOG_TAG, "reloading music info XML");
return reloadMusicInfo();
}
})
.share();
}
public Observable subscribeToMusicInfo() {
return mReloadingObservable;
}
public void triggerManualRefresh() {
mManualRefreshesSubject.onNext(1l);
}Since, it seems to me, one should generally avoid Subjects and try to use only normal Observables instead my question is: Is there any way to this that does not need Subjects? Is this a case where using Subjects is the way to go?
And also: What are the main drawbacks of Subjects in general?
Solution
There is no rule like
one should generally avoid Subjects
You should just be careful around them, like you have. Just as a rule of thumb, keep Subjects private (inside your class), and if you want the outside world to be able to subscribe to it, just call
As for your code, you can perform the
If you really have to remove the
Frankly, there is not much difference between either pattern. The only thing you should do is check whether the
one should generally avoid Subjects
You should just be careful around them, like you have. Just as a rule of thumb, keep Subjects private (inside your class), and if you want the outside world to be able to subscribe to it, just call
subject.asObservable.As for your code, you can perform the
setupObservable() inside an obervable.onSubscribe() so that you have a cold observable and not a hot one.If you really have to remove the
Subject, you can do a Observable.create(subsriber -> ...). This subscriber variable would be the replacement for your mManualRefreshesSubject.Frankly, there is not much difference between either pattern. The only thing you should do is check whether the
subject.isUnsubscribed() / subscriber.isSubscribed. One benifit of using a subscriber is that you make sure to do stuff onSubscribe and not before.Context
StackExchange Code Review Q#84304, answer score: 6
Revisions (0)
No revisions yet.