2016-11-23 160 views
0

我有以下類:呼叫對象的發射另一個改造呼叫

public class SessionStore { 
    Subject<Session, Session> subject; 

    public SessionStore() { 
     subject = new SerializedSubject<>(BehaviorSubject.create(new Session()); 
    } 

    public void set(Session session) { 
     subject.onNext(session); 
    } 

    public Observable<UserSession> observe() { 
     return subject.distinctUntilChanged(); 
    } 
} 

在活動我觀察了會議,並在每個變化進行網絡操作:

private Subscription init() { 
    return sessionStore 
      .observe() 
      .flatMap(new Func1<Session, Observable<Object>>() { 
       @Override 
       public Observable<Object> call(Session session) { 
        return (session.isValid() 
         ? retrofitService.getThingForValid() 
         : retrofitService.getThingForInalid()) 
         .subscribeOn(Schedulers.io()); 
       } 
      }) 
      .subscribe(...); 
} 

現在我有一個Okhttp請求攔截器,當網絡響應是非200代碼時,我將會話實例從有效設置爲無效。

這是發生了什麼:

  1. 在初始訂閱會話店getThingForValid()執行和失敗。
  2. OkHttp攔截失敗並設置新會話。
  3. 會話存儲會發出新的,現在無效的會話。
  4. 新排放執行getThingForInvalid()方法。

重要的是要知道這個執行發生在前一次Retrofit調用中。這是因爲OkHttp客戶端被Retrofit包裝,並且所有攔截器都在Retrofit返回之前執行。

考慮到這一點,您意識到第二個調用正在被Retrofit執行和處理,而第一個調用還沒有完成。

  1. 第一次調用完成後,它會拋出HttpException,因爲響應是非200代碼。
  2. xception殺死了rx流並使用它進行第二次調用。

我試圖忽略流中的這個異常,但第二次調用通過Retrofit取消。

你有什麼想法如何使我的概念工作,請?

+0

你有沒有嘗試過'.onErrorResumeNext(err - > Observable.empty())'''靜脈? –

+0

是的,它有相同的輸出。它必須與改造內部結構有關,而不是與RxJava結合。 – bakua

+0

你能抽象地解釋一下,你試圖達到什麼樣的目標以及你原來的問題是什麼? –

回答

0

如果您在令牌到期的情況下得到的響應代碼401: 需要在添加AuthenticatorOkHttpClient.Builder

builder.authenticator(new Authenticator() { 
      @Override 
      public Request authenticate(Route route, Response response) throws IOException { 
       final LoginResponse newLoginResponse = refreshTokenClient.refreshToken(); 
       //save new token locally, if needed 
       return response 
         .request() 
         .newBuilder() 
         .removeHeader("Api-Auth-Token") // removing old header 
         .addHeader("Api-Auth-Token", newLoginResponse.getAuthToken()) 
         .build(); 
      } 
     }); 

其中

public interface RefreshTokenService { 

    @PUT("/api/v1/tokens") 
    LoginResponse refreshToken(); 

} 

但要注意:這Authenticator將運行每次當響應代碼是401

+0

是的,但我無法刷新我需要重新執行業務邏輯的流程。無論如何,我已經解決了我的問題,使用另一個平面地圖。我稍後會發布解決方案。謝謝 :) – bakua