Reputation: 2309
I use RxJava and Retrofit in an Android app to get data from server. I have test activity with this code.
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);
}
}
And a Singleton class to contain data from server during whole lifecycle of the app.
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();
}
}
So when my test Activity created first time, and immediately calls for CapabilitiesHolder.createIfNotExist().getCapabilities()
the tost is empty, because data in response needs some time to be loaded. When onCreate
called a bit later, everything's ok.
The question is, ho can I make (Using RxJava?) getCapabilities()
method wait for response from server, before being called.
Thanks in advance!
Upvotes: 1
Views: 1102
Reputation: 698
I'll suggest you to rebuild your class CapabilitiesHolder
class. If you want to use that holder like that you should not request any data inside constructor. Also blocking UI thread is bad practice.
private CapabilitiesHolder() {
//empty
}
public Observable<CapabilitiesResponse> getCapabilities() {
if(capabilities!=null){
return Observable.fromCallable(() -> capabilities);
} else {
return RestServiceFactory.get()
.getServerCapabilities()
.doOnNext(capabilitiesResponse -> capabilities = capabilitiesResponse);
}
}
Upvotes: 1
Reputation: 191701
Short answer - don't block the UI thread and wait for anything.
Move your Toast into the method that handles the response
private void handleResponse(CapabilitiesResponse capabilitiesResponse) {
if (capabilitiesResponse.isSuccess()) {
text = capabilitiesResponse.getSupportedCurrencies().get(0).getDescription();
// Toast here
} else {
RestErrorHandler.handle(null, capabilitiesResponse);
}
Upvotes: 1