I try to get some data from server.
Observable<List<Countries>> backendObservable = mCountriesApi.getCountries()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread());
backendObservable.doOnNext(list -> Log.d(TAG, "doOnNext"));
backendObservable.doAfterNext(list -> Log.d(TAG, "doAfterNext"));
backendObservable.doOnComplete(() -> Log.d(TAG, "doOnComplete"));
backendObservable.subscribe(new Observer<List<Country>>() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onNext(List<Country> value) {
Log.d(TAG, "doOnNext"));
}
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
}
});
It's works, I receive data into "onNext". But methods doOnNext, doAfterNext, doOnComplete doesn't call.
What i doing wrong ?
You got it right up until observeOn, what happened? You have to chain operators on Observable because they are immutable dataflow plans:
backendObservable = backendObservable.doOnNext(list -> Log.d(TAG, "doOnNext"));
backendObservable = backendObservable.doAfterNext(list -> Log.d(TAG, "doAfterNext"));
backendObservable = backendObservable.doOnComplete(() -> Log.d(TAG, "doOnComplete"));
or more concisely
Observable<List<Countries>> backendObservable = mCountriesApi.getCountries()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(list -> Log.d(TAG, "doOnNext"));
.doAfterNext(list -> Log.d(TAG, "doAfterNext"));
.doOnComplete(() -> Log.d(TAG, "doOnComplete"));
.subscribe(...);
Related
Since in Hot Observable , we must use backpressure strategy to prevent from crash but why we use backpressure for example in the following examples which are Cold type:
Example 1
// If we do not use backpressure, the program will crash
Flowable.interval(1, TimeUnit.MILLISECONDS, Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
#Override
public void accept(Long aLong) throws Exception {
// do smth
}
});
Example 2
Flowable.range(0, 1000000)
.onBackpressureBuffer()
.observeOn(Schedulers.computation())
.subscribe(new FlowableSubscriber<Integer>() {
#Override
public void onSubscribe(Subscription s) {
}
#Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer);
}
#Override
public void onError(Throwable t) {
Log.e(TAG, "onError: ", t);
}
#Override
public void onComplete() {
}
});
I create an Observable that runs every 20 seconds.
I need to show the progress Bar (UI component) before every round, in AsyncTask i used onPreExecute method.
How can I do that in RXJava2 ?
disposables = Observable
.interval(0, 20, TimeUnit.SECONDS)
.doOnNext(n -> MainCulc_actions())
.subscribeOn(Schedulers.io()) // Run on a background thread
.observeOn(AndroidSchedulers.mainThread()) // Be notified on the main thread
.subscribeWith(new DisposableObserver<Long>() {
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
}
#Override
public void onNext(Long res) {
UpdateTheUI();
avi.smoothToHide();
}
});
You can try doOnSubscribe. For example
disposables = Observable
.interval(0, 20, TimeUnit.SECONDS)
.doOnNext(n -> MainCulc_actions())
.subscribeOn(Schedulers.io()) // Run on a background thread
.observeOn(AndroidSchedulers.mainThread()) // Be notified on the main thread
.doOnSubscribe(s -> avi.showUI)
.subscribeWith(new DisposableObserver<Long>() {
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
}
#Override
public void onNext(Long res) {
UpdateTheUI();
avi.smoothToHide();
}
});
I was using this code in Retrofit and Rx Java 1 to return an observable from a Retrofit call like this:
mCompositeSubscription.add(
ServiceFactory.createRetrofitService().setLike(mediaId,sessionMgr.getAuthToken())
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<ResponseBody>() {
#Override
public final void onCompleted( ) {}
#Override
public final void onError(Throwable e) {
userMessageHandler.showDialog(mParentActivity,mParentActivity.getString(R.string.error_setting_data_title),
mParentActivity.getString(R.string.error_set_like_msg) + e.getMessage(),0);
}
#Override
public void onNext(ResponseBody response) { }
})
);
I can't figure out how to convert it to RX Java 2. I have come up with this but not sure it is right:
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new DisposableObserver<User>(){
#Override
public void onNext(User user) {
authMgr.setUser(user);
}
#Override
public void onError(Throwable t) {
mProgressDlg.dismiss();
alertDlg.showIt(mResources.getString(R.string.err_register),
t.getMessage(), "",
"", mParentActivity, JAlertDialog.POSITIVE,null);
}
#Override
public void onComplete() { }
});
You should be able to use the RxJava2 adapter in retrofit. This will allow you to have your Retrofit API return RxJava2 types.
Here's a solid example: https://medium.com/3xplore/handling-api-calls-using-retrofit-2-and-rxjava-2-1871c891b6ae
I came up with this but I'm still testing...
mCompositeDisposable.add( ServiceFactory.createRetrofitService().registerNewUser(BuildConfig.CLIENT_KEY, data.email,
data.fname, data.lname, data.birthday,data.city,
data.state, mAvatarUrl, coords, Long.toString(mSessionId) ,
data.pwd, layerMgr.getNonce() )
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<User>(){
#Override
public void onNext(User user) {
}
#Override
public void onError(Throwable t) {
mProgressDlg.dismiss();
alertDlg.showIt(mResources.getString(R.string.err_register),
t.getMessage(), "",
"", mParentActivity, JAlertDialog.POSITIVE,null);
}
#Override
public void onComplete() { }
}));
I'm trying to learn RxAndroi so question is like on Title.
1 Response From Multiple Observables
I want to get 1 response from this 2 requests.
Or options number 2 I also want know how to synchronize them.
Do second request after first is completed.
Example code:
Observable<List<CategoriesTreeModel>> categoriesTreeObservable = ApiManager.getInstanceApi().getCategoriesTree();
Subscription treeSubscription = categoriesTreeObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<CategoriesTreeModel>>() {
#Override
public void onCompleted() {
Log.e("CATALOG", "getCategoriesTree() complete");
}
#Override
public void onError(Throwable e) {
Log.e("CATALOG", "getCategoriesTree() error");
}
#Override
public void onNext(List<CategoriesTreeModel> categoriesTreeModels) {
Log.e("CATALOG", "getCategoriesTree() next");
}
});
Observable<ResponseModel<CategoriesResponse>> categoriesObservable = ApiManager.getInstanceApi().getCategories();
Subscription subscription = categoriesObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<ResponseModel<CategoriesResponse>>() {
#Override
public void onCompleted() {
Log.e("CATALOG", "getCategories() complete");
}
#Override
public void onError(Throwable e) {
Log.e("CATALOG", "getCategories() error");
}
#Override
public void onNext(ResponseModel<CategoriesResponse> categoriesResponseResponseModel) {
Log.e("CATALOG", "getCategories() onNext");
}
});
EDIT:
It's a correct whay ?
Observable.zip(categoriesObservable, categoriesTreeObservable, new Func2<ResponseModel<CategoriesResponse>, List<CategoriesTreeModel>, Object>() {
#Override
public Object call(ResponseModel<CategoriesResponse> categoriesResponseResponseModel, List<CategoriesTreeModel> categoriesTreeModels) {
for (int i = 0; i < categoriesResponseResponseModel.getList().size(); i++){
Log.e("RESPONSE", "CATEGORIES: " + categoriesResponseResponseModel.getList().get(i).getCategory_id() + " NAME: " + categoriesResponseResponseModel.getList().get(i).getTranslations().getPl_PL().getName());
}
for (int i = 0; i < categoriesTreeModels.size(); i++){
Log.e("RESPONSE", "TREE: ID " + categoriesTreeModels.get(i).getId() + " CHILD: " + (categoriesTreeModels.get(i).getChildren().size() > 0 ? " has children " : "no child"));
}
return null;
}
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
Read something about MVP pattern in order to separate data logic from view logic.
Most straightforward solution for "Do second request after first is completed." is presented below. This pattern is not the best in the world but at least it will give you some code you can reference to.
final Observable<String> firstObservable = Observable.just("A")
.delay(5, TimeUnit.SECONDS)
.doOnNext(new Action1<String>() {
#Override
public void call(String s) {
Log.d(TAG, "call: " + s);
}
});
firstObservable
.subscribe();
final Observable<String> secondObservable = firstObservable
.flatMap(new Func1<String, Observable<String>>() {
#Override
public Observable<String> call(String s) {
return Observable.just(s + "B").delay(2, TimeUnit.SECONDS); // Make some api call
}
});
secondObservable.subscribe(new Action1<String>() {
#Override
public void call(String s) {
Log.d(TAG, "call: " + s);
}
});
How can I bind two subscriptions like:
1) Retrofit&RX which converts JSON into list of strings shown in recyclerView.
restClient.getCatFacts()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<CatFactsResponse>() {
#Override
public void onCompleted() {
Log.i(TAG, "onCompleted");
}
#Override
public void onError(Throwable e) {
Log.i(TAG, "onError, " + e.getMessage());
}
#Override
public void onNext(CatFactsResponse catFactsResponse) {
catFactsList = catFactsResponse.getCatFacts();
}
});
2) And Jack Wharton's RxBinding library to react to changes made in EditText widget.
subscription = RxTextView
.textChangeEvents(editText)
.debounce(400, TimeUnit.MILLISECONDS)
.observeOn(Schedulers.newThread())
.subscribe(new Observer<TextViewTextChangeEvent>() {
#Override
public void onCompleted() {
Log.i(TAG, "onCompleted");
}
#Override
public void onError(Throwable e) {
Log.i(TAG, "onError >> " + e.getMessage());
}
#Override
public void onNext(TextViewTextChangeEvent textViewTextChangeEvent) {
Log.i(TAG, textViewTextChangeEvent.text().toString());
}
});
to get list which is dynamically filtered using EditText. Am I supposed to use classes like Subject or sth? If yes, then how should it look like? Thanks for help :)
You should use flatMap operator
subscription = RxTextView
.textChangeEvents(editText)
.debounce(400, TimeUnit.MILLISECONDS)
.map(new Func1<TextViewTextChangeEvent, String>() {
#Override
public String call(TextViewTextChangeEvent textViewTextChangeEvent) {
return textViewTextChangeEvent.text();
}
})
.flatMap(new Func1<String, Observable<CatFactsResponse>>() {
#Override
public Observable<CatFactsResponse> call(String text) {
return restClient.getCatFacts(text)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
})
.subscribe(...);