Rx Android - 等待服务器响应

时间:2017-02-10 14:26:10

标签: android retrofit rx-java rx-android

我在Android应用中使用RxJava和Retrofit从服务器获取数据。我有这段代码的测试活动。

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

因此,当我的测试Activity第一次创建,并立即调用CapabilitiesHolder.createIfNotExist().getCapabilities()时,tost为空,因为响应中的数据需要一些时间来加载。当onCreate稍后调用时,一切都还可以。

问题是,我可以在调用之前使用(使用RxJava?)getCapabilities()方法等待来自服务器的响应。

提前致谢!

2 个答案:

答案 0 :(得分:1)

简短回答 - 不要阻止UI线程并等待任何事情。

将Toast移动到处理响应的方法

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

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