2017-02-10 90 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); 
    } 
}