0

カスタム Application サブクラスで 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 は最後に発行された値を発行します。なぜ私はこのようにしたいのですか?たとえば、ニュース アイテムがあり、ニュース フィードをフェッチし、ニュース アイテムの完全なコンテンツをフェッチするバックグラウンド タスクを開始したいとします。この場合、ニュース リストをスクロールしている間にデータのフェッチを開始できます。詳細なアクティビティをクリックすると、次のことができます。すでに取得したものから表示するか、ダウンロードするだけです。

4

1 に答える 1

2

アプリケーションの初期化中に createObservables() が一度だけ呼び出される限り、これは完全に安全だと思います。いくつかの提案された変更...

getFriends() からの戻り値で mFriends の BehaviorSubject 部分を公開しません。そうすれば、getFriends() の呼び出し元が onNext() を呼び出そうとすることはありません。次のように変更します。

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

非常に安全にしたい場合は、.asObservable() を使用すると、呼び出し元は戻り値を BehaviorSubject にキャストすることさえできなくなります。

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

また、サブスクライブ コールバックから BehaviorSubject onNext() を呼び出すように createObservable() メソッドを更新します。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.
            }
        });
于 2014-08-28T03:49:55.960 に答える