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()
}
Related
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
I use retrofit2 in my project. I have interface:
public interface ProductService {
#POST("findProducts")
Observable<ProductsResponse> getProducts();
}
and service method:
public ProductService getProductService() {
return getService(ProductService.class);
}
After that I use this service in my fragment. When I click to button I call this method:
#Override
public void onClick(View view) {
if (view.getId() == R.id.button) {
RestApiFactory.getInstance().getProductService().getProducts()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new ProductHandler());
}
}
and realise handler in this fragment:
private class ProductHandler implements Observer<ProductsResponse> {
#Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe: start");
progressBar.setVisibility(View.VISIBLE);
}
#Override
public void onNext(ProductsResponse value) {
//save to DB in new Thread
}
#Override
public void onError(Throwable e) {
Log.d(TAG, "onError: "+ e.getMessage());
price.setVisibility(View.INVISIBLE);
progressBar.setVisibility(View.INVISIBLE);
}
#Override
public void onComplete() {
Log.d(TAG, "onComplete: finish");
price.setVisibility(View.INVISIBLE);
progressBar.setVisibility(View.INVISIBLE);
}
}
is it correct to implement ProductHandler implements Observer<ProductsResponse>'s methods
onSubscribe
onNext
onError
onComplete
in fragment?
I'm advised to move this in a singleton:
MySingleton.getInstanse().getData();
and move all to getData :
public void getData(){
RestApiFactory.getInstance().getProductService().getProducts()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ProductsResponse>() {
#Override
public void onSubscribe(Disposable d) {
//send broadcast and catch in Fragment
}
#Override
public void onNext(ProductsResponse productsResponse) {
//send broadcast and catch in Fragment
}
#Override
public void onError(Throwable e) {
//send broadcast and catch in Fragment
}
#Override
public void onComplete() {
//send broadcast and catch in Fragment
}
});
}
but I think this is nonsense. who will tell you how to use it (in what place) Observable from retrofit?
there is no need to implement Observer.You can just need to create an observer for the same.Let's see the example.
service.getProducts()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(mObserver);
}
the observer should look like and must be initialized in oncreate:
mObserver = new Observer<ProductsResponse>() {
#Override
public void onSubscribe(Disposable d) {
mDisposableList.add(d);
}
#Override
public void onNext(ProductsResponse value) {
#Override
public void onError(Throwable e) {
e.printStackTrace();
}
#Override
public void onComplete() {
}
};
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?
Recently I have been working on RxJava 2 and I have tested the Observable.interval()
subscription = Observable.interval(1, TimeUnit.MILLISECONDS, Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
subscription.subscribe(new Observer<Long>() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onNext(Long aLong) {
//binding.appBar.mainContent.msg.setText(aLong+"");
}
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
}
});
Observable is started after activity's onCreate method. And I am logging the output through onNext() method. And I have a Stop Button. When it is triggered I want to stop subscription flow.
Even after the stop button is clicked the log keeps on going.
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (subscription != null) {
subscription.unsubscribeOn(Schedulers.io());
}
}
});
You have subscribed with an Observer, which means you have to keep a reference to the actual Disposable from onSubscribe(Disposable) callback, and later perform Disposable#dispose() on that object.
private Disposable disposable;
...
Observable.interval(1, TimeUnit.MILLISECONDS, Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
new Observer() {
#Override public void onSubscribe(Disposable d) {
disposable = d;
}
// other callbacks here
});
disposable.dispose();
Instead you can change your subscription to following:
Disposable disposable = Observable.interval(1, TimeUnit.MILLISECONDS, Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
#Override public void accept(Long aLong) throws Exception {
// onNext
}
}, new Consumer() {
#Override public void accept(Throwable throwable) throws Exception {
// onError
}
}, new Action() {
#Override public void run() throws Exception {
// onComplete
}
});
disposable.dispose();
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() {
}
});
}
}