Использование Observable в пользовательском подклассе приложения

Допустимо ли создавать Rx Observables в пользовательском подклассе приложения. Причина этого в том, что я могу создать BehaviorSubject внутри приложения и каждые 10 минут запрашивать изменения с сервера, каждое действие или фрагмент, который подписывается на этот Observable, получит только последнее состояние изменений.

Вопрос в том, можно ли считать эту архитектуру безопасной с точки зрения управления жизненным циклом приложений и простой в использовании?

class CustomApplication extends Application {
   ...

   BehaviorSubject<Friends> mFriends = new BehaviorSubject<Friends>;
   public void createObservables() {
      Observable.create(new Observable.OnSubscribe<Friends>() {
         public void call(Subscriber<?> s) {
            while(true) {
               mFriends.onNext("randomFriendN");
               sleep(10sec);
            }
         }
      })
      .subscribeOn(Schedulers.newThread())
      .subscribe(new Observer<List<NewsCategory>>() {
         public void onNext(Friends f) { //empty }
      });
   }
   public BehaviorSubject<Friends> getFriends() {
      return mFriends;
   }
}

ОБНОВЛЕНИЕ: Каждый раз, когда создается новое действие и оно хочет получить данные, оно может получить его в ApplicationContext BehaviorSubject, а затем подписаться на него, и Subject будет выдавать последнее переданное значение; Почему я хочу сделать так? Например. Допустим, у вас есть новости, вы получили новостную ленту и хотите запустить фоновую задачу, которая извлекает полное содержимое новости, в этом случае я могу начать извлекать данные, пока вы прокручиваете список новостей, и когда вы нажимаете подробную активность, мы можем показать его из уже загруженного или просто скачайте его.


person user1831986    schedule 17.05.2014    source источник
comment
Не могли бы вы предоставить какой-нибудь псевдокод, чтобы устранить любую двусмысленность?   -  person nhaarman    schedule 17.05.2014
comment
снабжен своего рода псевдокодом, спасибо за совет   -  person user1831986    schedule 17.05.2014
comment
Просто советы по улучшению: BehaviorSubject также является наблюдателем. Вы можете подписаться (BehaviorSubject) напрямую.   -  person zsxwing    schedule 18.05.2014
comment
Для меня это не безопасно. Даже если вы отмените подписку на все из темы, Observable, отправляющий сообщение в тему, никогда не будет собирать мусор. Если вы дважды вызовете createObservables, обе наблюдаемые будут существовать вечно (особенно потому, что это в приложении).   -  person Akito    schedule 25.05.2014


Ответы (1)


Я думаю, что это совершенно безопасно, поскольку createObservables() вызывается только один раз во время инициализации приложения. Несколько предложенных изменений...

Я бы не стал раскрывать часть BehaviorSubject mFriends в возвращаемом значении из getFriends(). Таким образом, у вызывающих getFriends() не будет соблазна вызвать onNext(). Измените его на:

public Observable<Friends> getFriends() {
    return mFriends;
}

Если вы хотите быть очень безопасным, используйте .asObservable(), и вызывающие абоненты даже не смогут вернуть возвращаемое значение обратно в BehaviorSubject.

public Observable<Friends> getFriends() {
    return mFriends.asObservable();
}

Я бы также обновил ваш метод createObservable(), чтобы он вызывал BehaviorSubject onNext() из обратного вызова подписки. Вот ваш код, слегка измененный для использования NewsItems.

BehaviorSubject<List<NewsItem>> mNewsItemSubject = BehaviorSubject.create();

void createObservables() {
    Observable
            .timer(10, 10, TimeUnit.SECONDS, Schedulers.newThread())
            .flatMap(new Func1<Long, Observable<List<NewsItem>>>() {
                @Override
                public Observable<List<NewsItem>> call(Long aLong) {
                    // Normally you would create a network API that returns Observable<NewsItem>.
                    // For now just pretend this returned Observable makes an Observable
                    // network request.
                    return Observable.just(
                            Arrays.asList(
                                    new NewsItem("fakeNewsItem"),
                                    new NewsItem("fakeNewsItem1")
                            )
                    );
                }
            })
            .subscribe(new Action1<List<NewsItem>>() {
                @Override
                public void call(List<NewsItem> newsItems) {
                    mNewsItemSubject.onNext(newsItems);
                }
            });
}

public Observable<List<NewsItem>> observeNewsItems() {
    return mNewsItemSubject;
}

Затем ваши действия Android могут вызывать ((CustomApplication)getApplication()).observeNewsItems(), чтобы получать последние новости и любые обновления, пока действие отображается.

final Observable<List<NewsItem>> newsItemsObservable = 
    ((CustomApplication) getApplication()).observeNewsItems();

newsItemsObservable
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<List<NewsItem>>() {
            @Override
            public void onCompleted() {
                // All done.
            }

            @Override
            public void onError(Throwable e) {
                // Notify user of error (maybe)
            }

            @Override
            public void onNext(List<NewsItem> newsItems) {
                // Update the UI with newsItems.
            }
        });
person kjones    schedule 28.08.2014