RxJava Android threading boilerplate - android

Few days ago I have faced with the treading rx problem. I was thinking how the rxJava threading works. This code didn't want to run on another thread.
mAPIInterface.getAllProjects(accessToken)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<Project>>() {
#Override
public void onSubscribe(#NonNull Disposable d) {
mView.showLoadProgress();
}
#Override
public void onNext(#NonNull List<Project> allProjects) {
projects = allProjects;
mView.hideLoadProgress();
mView.onProjectsLoaded();
}
#Override
public void onError(#NonNull Throwable e) {
mView.hideLoadProgress();
mView.onProjectsLoadError();
}
#Override
public void onComplete() {
}
});
Then I have find the solution but I'm still not sure if it's ok. That's look like there are some more good solution:
mAPIInterface.getAllProjects(accessToken)
.subscribeOn(Schedulers.newThread())
.map(new Function<List<Project>, List<Project>>() {
#Override
public List<Project> apply(#NonNull List<Project> projects) throws Exception {
return projects;
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<Project>>() {
#Override
public void onSubscribe(#NonNull Disposable d) {
mView.showLoadProgress();
}
#Override
public void onNext(#NonNull List<Project> allProjects) {
projects = allProjects;
mView.hideLoadProgress();
mView.onProjectsLoaded();
}
#Override
public void onError(#NonNull Throwable e) {
mView.hideLoadProgress();
mView.onProjectsLoadError();
}
#Override
public void onComplete() {
}
});
With that map() middleware it works. But should I use that everytime when I need to run the process on another thread?

Related

How to call manually onNext method in RxJava?

I need help for RxJava. Everything is working fine. But I want to call onNext manually in my other method.
Observable<Data> mylist = Observable.fromIterable(datalist);
mylist.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.buffer(6)
.subscribe(new Observer<List<Data>>() {
#Override
public void onSubscribe(Disposable d) { }
#Override
public void onNext(List<Data> list) {
myadapter.addData(list);
}
#Override
public void onError(Throwable e) {}
#Override
public void onComplete() { fetchNextPage(); }
});
Like this:
OnloadMore() {
onNext()
}

How to delay loading items by using RxJava?

While inflating Android view I load a bunch of stuff from the background thread and inflate some views based on network responses. So I am trying to defer some of that tasks using RxJava like this
Single.fromCallable(() -> savedInstanceState)
.delay(50,TimeUnit.MICROSECONDS,AndroidSchedulers.mainThread())
.flatMapCompletable(this::loadVideos)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
#Override
public void onSubscribe(Disposable d) {
Timber.d("on Subscribe");
}
#Override
public void onComplete() {
Timber.d("on onComplete");
}
#Override
public void onError(Throwable e) {
Timber.d("on onError");
}
});
And the loadVideos method is like this:
private Completable loadVideos(Bundle savedInstanceState) {
return Completable.fromAction(() -> {
videoPresenter.loadVideos(savedInstance);
});
}
What I am finding is onSubscribe() certainly gets called, but method videoPresenter.loadVideos never gets called. Would appreciate if anyone can point out what I am doing wrong.
For my testing, I implemented following test that seems to work...
public class DelayTest {
public static void main(String[] args) throws InterruptedException {
Single.fromCallable(() -> "hello")
.delay(50, TimeUnit.MICROSECONDS)
.flatMapCompletable(new Function<String, CompletableSource>() {
#Override
public CompletableSource apply(String s) throws Exception {
return getFlatMapCompletable();
}
})
.subscribe(new CompletableObserver() {
#Override
public void onSubscribe(Disposable d) {
System.out.println("In onSubscribe");
}
#Override
public void onComplete() {
System.out.println("In onComplete");
}
#Override
public void onError(Throwable e) {
System.out.println("In onError");
}
});
Thread.sleep(200L);
}
private static Completable getFlatMapCompletable() {
return Completable.fromAction(new Action() {
#Override
public void run() throws Exception {
System.out.println("In flatmapCompletable");
}
});
}
}
Delay operator in RxJava is executed in another thread. So the rest of the execution does not wait for this one to be finished.
Take a look to some examples https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/utils/ObservableDelay.java

zip rxjava operator cannot resolve method subscribe

I want to send multiple requests over the network and this tutorial
helped but i'm stuck at the latter part .
seems i'm expected to return a value(OrderValues) from onSubscribe,onNext,....
since apply function returns a value. But ....,onNext returns void by default.
Any help?Here is my piece of code
Observable<Restaurant> orderRestaurant= IdentityClient.getAPIService()
.getRestaurantById(restaurantId)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread());
Observable<Menu> orderMenu= IdentityClient.getAPIService()
.getMenuById(menuId)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread());
Observable<User> orderUser= IdentityClient.getAPIService()
.getUserById(userId)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread());
Observable<OrderValues> combineValues=Observable.zip(orderRestaurant,
orderMenu, orderUser,
new Function3<Restaurant, Menu, User, OrderValues>() {
#Override
public OrderValues apply(Restaurant restaurant, Menu menu, User user)
throws Exception {
return new OrderValues(restaurant,menu,user);
}
I get an error here "cannot resolve method 'subscribe anonymous
org.reactivestreams.Subscriber(....OrderValues)
}).subscribe(new Subscriber<OrderValues>() {
#Override
public void onSubscribe(Subscription s) {
}
#Override
public void onNext(OrderValues orderValues) {
}
#Override
public void onError(Throwable t) {
}
#Override
public void onComplete() {
}
});
I'm assuming that you are using RxJava 2.
Use Observer instead of Subscriber. And also do not assign the result to a new Observable (you called it combineValues).
private void myMethod() {
Observable.zip(orderRestaurant, orderMenu, orderUser, new Function3<Restaurant, Menu, User, OrderValues>() {
#Override
public OrderValues apply(#NonNull Restaurant restaurant, #NonNull Menu menu, #NonNull User user) throws Exception {
return new OrderValues(restaurant, menu, user);
}
}).subscribe(new Observer<OrderValues>() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onNext(OrderValues orderValues) {
}
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
}
});
}
}

RxAndroid interval API call. Is there a better way?

Am doing a weather API call every 3secs and append the result to a textView using showWeather("weather") but I am sure there is a better way to do it. Am not sure why I need create Class Func1 but did because map required it. Also is there a way to shorten observer? I don't use lamda unfortunately. Any suggestions?
Observer myObserver = new Observer<String>() {
#Override
public void onError(Throwable e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
}
#Override
public void onComplete() {
}
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onNext(String value) {
showWeather(value);
}
};
class Func1<T, T1> implements io.reactivex.functions.Function<Long, String > {
#Override
public String apply(Long aLong) throws Exception {
return getJSON("http://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b1b15e88fa797225412429c1c50c122a1",300);
}
}
Observable.interval(3, TimeUnit.SECONDS)
.map(new Func1<Long, Observable<String>>() {
}).observeOn(AndroidSchedulers.mainThread()).subscribe(myObserver);
I tried :
Observable
.interval(3, SECONDS)
.subscribeOn(Schedulers.io())
.fromCallable(new Callable<String>() {
#Override
public String call() throws Exception {
return getJSON("http://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b1b15e88fa797225412429c1c50c122a1", 300);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(myObserver)
But I get :
03-07 21:47:25.982 21181-21181/com.alex.rxandroidexamples E/imerExampleFragment$1$1: null
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
Also how do I unsubscribe onPause or onPause?
I found out the best way to do this is :
private final CompositeDisposable disposables = new CompositeDisposable();
Observable fetchWeatherInterval = Observable.interval(3, TimeUnit.SECONDS)
.map(new Function<Long, String>() {
#Override
public String apply(Long aLong) throws Exception {
return getWeather("http://samples.openweathermap.org/data/2.5/weather?", "London,uk", "b1b15e88fa797225412429c1c50c122a1");
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
Observer displayWeatherInterval = new Observer<String>() {
#Override
public void onError(Throwable e) {
Log.e("Throwable ERROR", e.getMessage());
}
#Override
public void onComplete() {
}
#Override
public void onSubscribe(Disposable d) {
disposables.add(d);
}
#Override
public void onNext(String value) {
textViewWeatherInterval.append(value);
}
};
buttonFetchIntervalWeather.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
fetchWeatherInterval.subscribe(displayWeatherInterval);
}
});

Retry only failed observable RxJava 2

I'm trying to run a long running task that might fail for some objects in a list I tried retry but it resubscribes to the entire list of observables. I can do nested subscriptions but it seems wrong. Is there any better solution than nesting subscriptions?
Here is my implementation:
public Observable<ReportItemModel> deferReports() {
return Observable.defer(new Callable<ObservableSource<? extends ReportItemModel>>() {
#Override
public ObservableSource<? extends ReportItemModel> call() throws Exception {
return Observable.fromIterable(getReports())
.map(new Function<Report, ReportItemModel>() {
#Override
public ReportItemModel apply(Report report) throws Exception {
return report.getReport();
}
});
}
});
}
reportFactory.deferReports()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.retry()
.subscribe(new Observer<ReportItemModel>() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onNext(ReportItemModel value) {
Log.d(TAG,value.toString());
}
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
}
});

Categories

Resources