2017-02-10 4 views
1

Ich benutze RxJava und Retrofit in einer Android App, um Daten vom Server zu bekommen. Ich habe Testaktivität mit diesem Code.Rx Android - Warte auf Server Antwort

String text; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     viewMenu = (LinearLayout) findViewById(R.id.view_menu); 
     tabMenu.initTabBar(viewMenu, this); 
     CapabilitiesHolder.createIfNotExist().getCapabilities().subscribe(this::handleResponse, RestErrorHandler::handle); 
     Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); 
    } 



    private void handleResponse(CapabilitiesResponse capabilitiesResponse) { 
     if (capabilitiesResponse.isSuccess()) { 
      text = capabilitiesResponse.getSupportedCurrencies().get(0).getDescription(); 
     } else { 
      RestErrorHandler.handle(null, capabilitiesResponse); 
     } 
    } 

Und eine Singleton-Klasse, die Daten vom Server während des gesamten Lebenszyklus der App enthält. So

public class CapabilitiesHolder { 


    private static CapabilitiesHolder mInstance = null; 

    private CapabilitiesResponse capabilities; 


    public static CapabilitiesHolder createIfNotExist() { 
     if (mInstance == null) { 
      mInstance = new CapabilitiesHolder(); 
     } 
     return mInstance; 
    } 

    private CapabilitiesHolder() { 
     requestCapabilities(); 
    } 

    public Observable<CapabilitiesResponse> getCapabilities() { 
     return Observable.fromCallable(() -> capabilities); 
    } 

    private CompositeSubscription compositeSubscription = new CompositeSubscription(); 

    private void requestCapabilities() { 
     Observable<CapabilitiesResponse> o = RestServiceFactory.get().getServerCapabilities(); 
     compositeSubscription.add(o.subscribe(this::handleResponse, RestErrorHandler::handle)); 
    } 

    private void handleResponse(CapabilitiesResponse capabilitiesResponse) { 
     if (capabilitiesResponse.isSuccess()) { 
      capabilities = capabilitiesResponse; 
     } else { 
      RestErrorHandler.handle(null, capabilitiesResponse); 
     } 
    } 

    public void update() { 
     mInstance = null; 
     mInstance = new CapabilitiesHolder(); 
    } 
} 

wenn meine Testaktivität ersten Mal erstellt wurde, und ruft sofort für CapabilitiesHolder.createIfNotExist().getCapabilities() die tost leer ist, weil die Daten in Reaktion braucht einige Zeit geladen werden. Wenn onCreate ein bisschen später aufgerufen wird, ist alles in Ordnung.

Die Frage ist, ho kann ich machen (Using RxJava?) getCapabilities() Methode warten auf Antwort vom Server, bevor sie angerufen werden.

Vielen Dank im Voraus!

Antwort

1

Kurze Antwort - blockieren Sie den UI-Thread nicht und warten Sie auf nichts.

Ihren Toast in die Methode verschieben, dass die Antwort werde ich

private void handleResponse(CapabilitiesResponse capabilitiesResponse) { 
    if (capabilitiesResponse.isSuccess()) { 
     text = capabilitiesResponse.getSupportedCurrencies().get(0).getDescription(); 
     // Toast here 
    } else { 
     RestErrorHandler.handle(null, capabilitiesResponse); 
    } 
+0

Danke für den Rat. Aber wie gesagt, das ist eine Testaktivität, So Toast wird überhaupt entfernt. Die Kernfrage war, wie kann man 'CapabilitiesHolder.createIfNotExist(). GetCapabilities()' dieses Ergebnis zurückgeben, wenn es fertig ist, anstatt 'null' nach dem ersten Aufruf zurückzugeben. –

+1

Es gibt keine Null zurück. Die getCapabilities-Methode blockiert nicht (und sollte nicht). Die Anfrage ist an der Stelle Ihrer Toast-Methode einfach nicht beendet. –

+1

Sie haben Ihre Callback-Handler die Antwort festgelegt. Es spielt keine Rolle, ob Sie Ihre Benutzeroberfläche toasten oder aktualisieren. Sag ich doch –

1

Griffe empfehlen Ihnen, Ihre Klasse CapabilitiesHolder Klasse neu zu erstellen. Wenn Sie diesen Halter so verwenden möchten, sollten Sie keine Daten innerhalb des Konstruktors anfordern. Auch das Blockieren des UI-Threads ist schlechte Übung.

private CapabilitiesHolder() { 
    //empty 
} 

public Observable<CapabilitiesResponse> getCapabilities() { 
    if(capabilities!=null){ 
     return Observable.fromCallable(() -> capabilities); 
    } else { 
     return RestServiceFactory.get() 
       .getServerCapabilities() 
       .doOnNext(capabilitiesResponse -> capabilities = capabilitiesResponse); 
    } 
} 
Verwandte Themen