Rx Android - 等待服务器响应
Rx Android - wait for server response
我在 Android 应用程序中使用 RxJava 和 Retrofit 从服务器获取数据。我用这段代码测试了 activity。
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);
}
}
和一个单例 class 以在应用程序的整个生命周期中包含来自服务器的数据。
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()
方法在被调用之前等待来自服务器的响应。
提前致谢!
简短回答 - 不要阻塞 UI 线程并等待任何事情。
将 Toast 移动到处理响应的方法中
private void handleResponse(CapabilitiesResponse capabilitiesResponse) {
if (capabilitiesResponse.isSuccess()) {
text = capabilitiesResponse.getSupportedCurrencies().get(0).getDescription();
// Toast here
} else {
RestErrorHandler.handle(null, capabilitiesResponse);
}
我会建议您重建 class CapabilitiesHolder
class。如果你想像那样使用那个持有人,你不应该在构造函数中请求任何数据。阻塞 UI 线程也是 不好的做法。
private CapabilitiesHolder() {
//empty
}
public Observable<CapabilitiesResponse> getCapabilities() {
if(capabilities!=null){
return Observable.fromCallable(() -> capabilities);
} else {
return RestServiceFactory.get()
.getServerCapabilities()
.doOnNext(capabilitiesResponse -> capabilities = capabilitiesResponse);
}
}
我在 Android 应用程序中使用 RxJava 和 Retrofit 从服务器获取数据。我用这段代码测试了 activity。
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);
}
}
和一个单例 class 以在应用程序的整个生命周期中包含来自服务器的数据。
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()
方法在被调用之前等待来自服务器的响应。
提前致谢!
简短回答 - 不要阻塞 UI 线程并等待任何事情。
将 Toast 移动到处理响应的方法中
private void handleResponse(CapabilitiesResponse capabilitiesResponse) {
if (capabilitiesResponse.isSuccess()) {
text = capabilitiesResponse.getSupportedCurrencies().get(0).getDescription();
// Toast here
} else {
RestErrorHandler.handle(null, capabilitiesResponse);
}
我会建议您重建 class CapabilitiesHolder
class。如果你想像那样使用那个持有人,你不应该在构造函数中请求任何数据。阻塞 UI 线程也是 不好的做法。
private CapabilitiesHolder() {
//empty
}
public Observable<CapabilitiesResponse> getCapabilities() {
if(capabilities!=null){
return Observable.fromCallable(() -> capabilities);
} else {
return RestServiceFactory.get()
.getServerCapabilities()
.doOnNext(capabilitiesResponse -> capabilities = capabilitiesResponse);
}
}