2016-12-10 3 views
2

Ich versuche, 3 Dienste gleichzeitig anzufordern und das Ergebnis zu zeigen, wenn sie alle konkurrieren. Alles ist in Ordnung, bis eine der Anfragen fehlgeschlagen ist.Rxjava mit Nachrüstung - zip() - wie man eine Fehlerreaktion umgeht

public class MainActivity extends AppCompatActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    testZip(); 
} 

private void testZip() { 
    Retrofit repo = new Retrofit.Builder() 
      .baseUrl("https://api.github.com") 
      .addConverterFactory(GsonConverterFactory.create()) 
      .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
      .build(); 

    Observable<JsonObject> userObservable = repo 
      .create(GitHubUser.class) 
//    .getUser("username") 
       .getUser("fakeUser_fakeUser") 
       .subscribeOn(Schedulers.newThread()) 
       .observeOn(AndroidSchedulers.mainThread()); 

    Observable<JsonArray> eventsObservable = repo 
      .create(GitHubEvents.class) 
      .listEvents("username") 
      .subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()); 

    Observable<UserAndEvents> combined = Observable.zip(userObservable, eventsObservable, new Func2<JsonObject, JsonArray, UserAndEvents>() { 
     @Override 
     public UserAndEvents call(JsonObject jsonObject, JsonArray jsonElements) { 
      return new UserAndEvents(jsonObject, jsonElements); 
     } 
    }).onErrorResumeNext(Observable.<UserAndEvents>empty()); 

    combined.subscribe(new Subscriber<UserAndEvents>() { 
     @Override 
     public void onCompleted() { 
      Log.wtf("TAG", "onCompleted"); 
     } 

     @Override 
     public void onError(Throwable e) { 
      Log.wtf("TAG", "onError"); 
      Log.wtf("TAG", e.toString()); 
     } 

     @Override 
     public void onNext(UserAndEvents o) { 
      Log.wtf("TAG", "onNext"); 
      Log.wtf("Username", o.user.get("name").toString()); 
      Log.wtf("First event", o.events.get(0).getAsJsonObject().get("type").toString()); 
     } 
    }); 
} 



public interface GitHubUser { 
    @GET("users/{user}") 
    Observable<JsonObject> getUser(@Path("user") String user); 
} 

public interface GitHubEvents { 
    @GET("users/{user}/events") 
    Observable<JsonArray> listEvents(@Path("user") String user); 
} 

public class UserAndEvents { 
    public UserAndEvents(JsonObject user, JsonArray events) { 
     this.events = events; 
     this.user = user; 
    } 

    public JsonArray events; 
    public JsonObject user; 
} 

}

Was will ich hier auf „Ereignisse“ Daten zu erhalten, auch wenn der Benutzer Anforderung fehlgeschlagen ist. Ich habe es mit onErrorReturn(), onErrorResumeNext(), onExceptionResumeNext() versucht, aber alle gehen auf onCompleted() ohne Daten. Ich wollte mergeDelayError() verwenden, aber es erfordert, dass die Antwortdaten die gleichen sind, die nicht zu meiner App passen.

Bitte lassen Sie mich wissen, wenn Sie irgendwelche Ideen haben. Danke vielmals.

+1

Sie können versuchen wiederholen() retryWhen() userObservable, eventsObservable Observable nicht kombiniert Observable –

Antwort

2

Verschieben onErrorResumeNext-userObservable, so zip wird wie Observable<UserAndEvents> combined = Observable.zip(userObservable.onErrorResumeNext(Observable.just(new JsonObject()), eventsObservable,... aussehen. Im Falle eines Fehlers enthält das gepackte Ergebnis ein leeres JsonObject für den Benutzer.

+0

Genius. Ich habe mit userObservable.onErrorResumeNext() versucht, aber eine Observable.empty() geworfen, also geht es zu onNext() ohne UserAndEvents Daten. Danke vielmals. – thanhbinh84

Verwandte Themen