Defer and fromCallable behavior in RxJava 2.x - android

I've read some RxJava2 issues about the crash after call dispose() on an Observable here and here. Then I tried to reproduce the crash by the code:
private String simulateHeavyWork() throws InterruptedException {
Thread.sleep(2000);
return "Done";
}
private void myFunc() {
Disposable disposable = Observable.fromCallable(() -> simulateHeavyWork())
.subscribeOn(Schedulers.io())
.subscribe(System.out::println, throwable -> System.out.println(throwable.getMessage()));
sleep(1000);
disposable.dispose();
sleep(60000);
}
When I ran the code, I got the exception io.reactivex.exceptions.UndeliverableException as expected. As the discussion in above link, RxJava2 will not swallow the Throwable so we have to handle this. But when I tried to use the defer instead of fromCallable to create the Observable, surprised me, no error was fired.
Disposable disposable = Observable.defer(() -> Observable.just(simulateHeavyWork()))
It surprises me again when I use Flowable instead of Observable, the UndeliverableException happened again.
Disposable disposable = Flowable.defer(() -> Flowable.just(simulateHeavyWork()))
So I'm confusing about the difference between defer and fromCallable, Flowable and Observable in this case.

Related

How to throw an exception using RxJava without OnNext

I'm trying to force throw an error during the fake downloading using RxJava:
disposable.add(fakeRepo.downloadSomething()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ a: String -> finished() },
{ b: Throwable? -> showError() }
))
fun downloadSomething(): Single<String> {
return Single.just("")
}
I found solutions only with onNext, but I don't want this in my code.
What I should do to invoke showError() ?
Currently I always get finished()
Just use Single.error:
http://reactivex.io/RxJava/javadoc/io/reactivex/Single.html#error-java.lang.Throwable-
public static Single error(Throwable exception)
Returns a Single that invokes a subscriber's onError method when the subscriber subscribes to it.

Handling Error RXJava Android with Kotlin

Hi I'm new with RxJava and Kotlin and I loose some concepts about it.
I have "api" like this:
interface VehiclesService {
#GET("/vehicles/")
fun getVehicles(): Single<List<Vehicle>>
}
Then I create the retrofit client, etc.. like this:
var retrofit = RetrofitClient().getInstance()
vehiclesAPI = retrofit!!.create(VehiclesService ::class.java)
finally I do the call:
private fun fetchData() {
compositeDisposable.add(vehiclesAPI .getVehicles()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { vehicles -> displayData(vehicles) }
)
}
And here is where I have the error when I try to launch:
The exception was not handled due to missing onError handler in the subscribe() method call
I know that the error is quite explicit. So I know what is missing, but what I don't know is HOW to handle this error.
I tried adding : .doOnError { error -> Log.d("MainClass",error.message) } but still telling same error message.
You can pass another lambda to subscribe to handle the errors for a specific stream like this:
private fun fetchData() {
compositeDisposable.add(vehiclesAPI .getVehicles()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe( { vehicles -> displayData(vehicles) }, { throwable -> //handle error } )
)
}
P.S: doOnError and other Side Effect operators, will not affect the stream in anyway, they just anticipate the values emitted for side-effect operations like logging for example.

How to cancel Observable execution with RxJava once all subscribers gets disposed

In my code I am creating an Observable like this -
Observable observable = Observable.fromCallable(new Callable<String>() {
#Override
public String call() throws Exception {
return longlongTask();
}
})
And then subscribing to it as -
Disposable disposable = observable.subscribeOn(Schedulers.single())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(string -> showResult(string)
My problem is even after I dispose my subscriber using disposable.dispose(), the Observable's long running task keeps on running until it finally completes. I would like to know if there is a way for me to stop this longlongTask once there are no subscribers listening to my Observable. Any methods/standard practices any of you have used to tackle this problem will be appreciated.

How to chain observables in rxjava2

I have two observables in my code. The first one is a merged observable for search button click and text change.
Observable<String> buttonClickStream = createButtonClickObservable();
Observable<String> textChangeStream = createTextChangeObservable();
Observable<String> searchTextObservable
=Observable.merge(buttonClickStream,textChangeStream);
disposable = searchTextObservable
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(s -> showProgressBar())
.observeOn(Schedulers.io())
.map(this::getStarredRepos)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(gitHubRepos -> {
hideProgressBar();
showResults(gitHubRepos);
});
The second observable is for getting response from server.:
private List<GitHubRepo> getStarredRepos(String username) {
RestInterface restService=RestService
.getClient().create(RestInterface.class);
restService.getStarredRepos(username)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(this::handleResponse, this::handleError);
return repoList;
}
Now the problem is, hideProgressBar() and showResults() methods are executing before handleResponse() finishes.
I am new to RxJava, so if there is anything wrong in code please rectify.
Your List<GitHubRepo> getStarredRepos(...) should instead be Observable<List<GitHubRepo>> getStarredRepos(...). Don't subscribe to the observable inside of this method, but return the observable you get from restService (if you need to process the response, put a map() before returning, for errors you can use onErrorReturn() or something you need).
Then instead of .map(this::getStarredRepos) do .switchMap(this::getStarredRepos).

Managing thread schedulers when concat observables

I have a code like this:
service.getUserById(10)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.concatMap(getFullUserFromDto())
.subscribe(doSomehingWithUser());
private Func1<UserDto, Observable<User>> getFullUserFromDto() {
return new Func1<UserDto, Observable<User>>() {
#Override
public Observable<User> call(final UserDto dto) {
return dao.getUserById(dto.getUserId());
}
};
}
and in my DAO, I have:
public Observable<User> getUserById(final Long id) {
return api.getUserById(id).map(//more things...
}
Note there are two levels of "concatenation": service -> dao -> api. Method api.getUserById(id) make a network call.
I'm getting NetworkOnMainThreadException error. Why? I'm using and subscribeOn and observeOn operators, but it seems that it is not applied to the "final" built Observable.
If I use this operators in the API call, in the DAO, it works:
return api.getUserById(id)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.map(//more things...
Is there a way to use just once in the "root" Observable?
So, concatMap subscribes on Observables. What thread is used to perform this operation? Well, the thread that called onNext for the concatMat, given that it doesn't change threads/schedulers. So, one simple transposition should help with this:
service.getUserById(10)
.subscribeOn(Schedulers.newThread())
.concatMap(getFullUserFromDto())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(doSomehingWithUser());
I'd also suggest to use Schedulers.io(), as it will re-use threads.
Short answer: use observeOn before chained operations to controll on which schedulers they are executed:
service.getUserById(10)
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.io())
.concatMap(getFullUserFromDto())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(doSomehingWithUser());
In the example above, .concatMap will be executed in Schedulers.io()
More details can be found here:
http://tomstechnicalblog.blogspot.com/2016/02/rxjava-understanding-observeon-and.html

Categories

Resources