2017-08-04 7 views
2

AndroidでRxJavaを使用してログイン操作を実行しています。変数を "into"にして後で使用するRxJavaチェーン

ユーザー名、パスワード、ブール値のフラグを渡す必要があります。ユーザー名とパスワードと検証のためにサーバーに送信され、応答が返されたら、次に何をするかを決定するためにフラグを使用する必要があります。

ログイン操作は非同期なので、応答が返っても私が最初に渡したユーザー名、パスワード、フラグにアクセスできるようにしたいと思います。

は、ここで私は問題を抱えていると信じていることを、私はこれをコード化された最初の方法です:

public Observable<Result> execute1(final String username, final String password, final boolean shouldSaveUsername) { 
    return mLoginNetwork 
      .loginWithCredentials(username, password) 
      .map(new Func1<Response<Void>, LoginObject>() { 
       @Override 
       public LoginObject call(Response<Void> response) { 
        if (!response.isSuccessful()) { 
         Exceptions.propagate(new HttpException(response)); 
        } 

        return new LoginObject(username, password, shouldSaveUsername); 
       } 
      }) 
      .doOnNext(new Action1<LoginObject>() { 
       @Override 
       public void call(LoginObject loginObject) { 
        if (loginObject.shouldSaveUsername) { 
         saveUsername(username); 
        } 
       } 
      }) 
      .flatMap(new Func1<Entitlement, Observable<Result>>() { 
       @Override 
       public Observable<Result> call(LoginObject loginObject) { 
        return mNetwork 
          .fetchSomething(); 
       } 
      }); 
} 

私は()それは私がキャッシュし、その後に加入した観測を返すEXECUTE1を呼び出すとき。 Androidの設定が変更された場合、私はObservableから退会しますが、キャッシュに保持します。構成の変更が完了したら、Observableをキャッシュから取り出して再サブスクライブします。私はresubscribe loginWithCredentials呼び出しを再度行う必要がありますが、それはユーザー名、パスワード、ブール値フラグが存在しないので、私は問題である私のチェーンでそれらを使用することはできませんが返されます。

この問題を解決するにはどうすればよいですか?

Observableの入力データをObservableの一部にする方法が必要です。Observableをキャッシュすると、入力データもキャッシュされるようになります。ここで

は、以下の提案されたソリューションです:私がしようとしてる何

public Observable<Result> execute2(String username, String password, boolean shouldSaveUsername) { 
    return Observable 
      .just(new LoginData(username, password, shouldSaveUsername)) 
      .flatMap(new Func1<LoginData, Observable<LoginData>>() { 
       @Override 
       public Observable<?> call(final LoginData loginData) { 
        return mLoginNetwork 
          .loginWithCredentials(loginData.getUsername(), loginData.getPassword()) 
          .map(new Func1<Response<Void>, LoginData>() { 
           @Override 
           public LoginData call(Response<Void> response) { 
            if (!response.isSuccessful()) { 
             Exceptions.propagate(new HttpException(response)); 
            } 
            return loginData; 
           } 
          }); 
       } 
      }) 
      .doOnNext(new Action1<LoginData>() { 
       @Override 
       public void call(LoginData loginData) { 
        if (loginData.shouldSaveUsername) { 
         saveUsername(username); 
        } 
       } 
      }) 
      .flatMap(new Func1<LoginData, Observable<Result>>() { 
       @Override 
       public Observable<Result> call(LoginData loginData) { 
        return mNetwork 
          .fetchSomething(); 
       } 
      }); 
} 

Observable.justを(使用してすぐにストリームの入力データ部分を作ることです)、入力データを取ると、 Observableにして、残りの残りの操作を入力として受け取るようにします。私は今、観測可能なデータをキャッシュし、後で再登録すると、入力データが観測可能な状態に埋め込まれ、後でどの演算子でもアクセスできると仮定します。

「正常な」RxJava /機能的な方法で私の提案したソリューションで私の問題を解決しましたか?この問題にアプローチするより良い方法はありますか?

+0

観測所を使用していません。これは、スレッドまたはAsyncTaskを使用してパラメータを渡すより簡単ですか?このコードは絶対に読めません。彼らは実際にあなたのための問題を解決するのではなく、彼らがクールな新しいものであるという理由だけで、観測可能物を使用しているようです。 –

+0

@GabeSechanこれは私が持っている概念的な問題を説明するための単純化されたシナリオです。私の実際の生活のシナリオでは、ログイン部分はちょうど始まりです。その後、さらに3つのAPIコールを作成して、より多くのデータをフェッチし、フィルタリングし、変換する必要があります。これはRxjavaの大きなユースケースです。 – neonDion

+0

それはフェッチされたデータには意味をなさけるかもしれませんが、ログイン呼び出し自体には何もしません(フェッチされたデータについても疑問があります)。RxJavaの使用量の99%がコードの読み込みや保守が難しいことがわかります。それを見たことのない疑いの恩恵)。しかし、そうであっても、物事をより明確にしていないログインのためにそれを使用する理由はありません。私は、このようなリモートで何かを使ってコードレビューを拒否します。 –

答えて

1

username/password/save-flagは、finalとマークされたパラメータとしてexecute1()に渡されます。次に、匿名のネストされたクラスでは、それらの値を明示的に参照し、それらを「クローズ」します。結果として得られる観測可能なチェーンには、動作するために必要なすべてのものがあります。

observableを再度購読すると、元のusername/password/save-flagが使用されます。

+0

私は元の質問でこれを明確にしませんでしたが、execute1()メソッドを持つクラスは設定変更中に破棄され、ガベージコレクションに適格になりました。 execute1()メソッドから返されたオブザーバブルは、シングルトンでキャッシュされ、後で取得され、再びサブスクライブされます。それが私に再サブスクリプションされるとき、私は最終的なパラメータがもはや利用可能であるとは思わない。 – neonDion

+0

パラメータの*値*は、observableを作成したオブジェクトではなく、observableの存続期間中存在します。 「クローズオーバー」という用語は、クラスがインスタンス化されるときに、匿名クラスが参照のコピーを作成することを意味します。 –

+0

あなたは正しいです。私はいくつかの異なるテストを実行して、たとえ再サブスクリプションされた古い観察可能オブジェクトが古いパラメータを匿名クラスで使用していたという古い観察可能オブジェクトに新しいサブスクリプションを提出したとしても、 Javaの仕組みについての私の誤解。 – neonDion

関連する問題