# Using a Subject to trigger a music list to reload

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 Observable<Playlist> 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<MusicInfoResponse> mReloadingObservable;
private PublishSubject<Long> mManualRefreshesSubject = PublishSubject.<Long>create();

private void setupObservable() {

Observable<Long> timer = Observable.timer(0, 15, TimeUnit.SECONDS);

Observable<Long> pulses = Observable.merge(timer, mManualRefreshesSubject);

.flatMap(new Func1<Long, Observable<MusicInfoResponse>>() {

@Override
public Observable<MusicInfoResponse> call(Long aLong) {
}
})
.share();
}

public Observable<MusicInfoResponse> subscribeToMusicInfo() {
}

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?

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

• It just no occurred to me that I'd never accepted this answer until now... Sorry! – david.mihola Feb 4 '16 at 8:28