2017-02-10 91 views
1

我在Android應用程序中使用RxJava和Retrofit從服務器獲取數據。我使用此代碼進行測試活動。Rx Android - 等待服務器響應

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); 
     } 
    } 

在應用程序的整個生命週期中包含來自服務器的數據的Singleton類。

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(); 
    } 
} 

所以,當我的測試活動創造了第一次,並立即要求CapabilitiesHolder.createIfNotExist().getCapabilities()的託斯特是空的,因爲在響應數據需要加載一段時間。當稍後調用onCreate時,一切正常。

問題是,我可以使用(使用RxJava?)getCapabilities()方法等待來自服務器的響應,然後被調用。

在此先感謝!

回答

1

簡短的回答 - 不要屏蔽UI線程並等待任何東西。

將你的麪包成處理響應

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

感謝您的建議。但正如我所說,這是一個測試活動,所以Toast將被刪除。核心問題是我怎樣才能讓CapabilitiesHolder.createIfNotExist()。getCapabilities()這個函數在準備就緒時返回結果,而不是在第一次調用之後返回null。 –

+1

它不返回null。 getCapabilities方法不會(也不應該)阻塞。這個請求根本沒有在你的Toast方法中完成。 –

+1

你有你的回調處理程序設置響應。如果您正在敬酒或更新您的用戶界面,無所謂。這就是我所說的 –

1

我會建議您重建類CapabilitiesHolder類中的方法。如果你想使用那樣的持有者,你不應該在構造函數中請求任何數據。還阻塞UI線程是不好的做法

private CapabilitiesHolder() { 
    //empty 
} 

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