I\'m getting a list of installed apps on the device. It\'s a costly operation, so I\'m using Rx for that:
Observable observable = Observable
.doOnError()
is an operator, and is not as such a part of the Subscriber
.
Therefore, having a .doOnError()
does not count as an implemented onError()
.
About the question in one of the comments, of course it is possible to use lambdas.
In this case simply replace
.doOnError(throwable -> L.e(TAG, "Throwable " + throwable.getMessage()))
.subscribe(s -> createListView(s, view))
with
.subscribe(s -> createListView(s, view),
throwable -> L.e(TAG, "Throwable " + throwable.getMessage()))
My take is: you are probably using Action1 in
.subscribe(s -> createListView(s, view));
You will need to replace it with Subscriber or Observer which has abstract method onError
. This method will be called from subscriber.onError(new Throwable());
EDIT:
This is how I would do it. Upon closer look I think the main problem in your code is the early part where you call subscriber.onError
even when there's no error. You probably don't need map
either because you are technically passing data as-is without manipulation. But I left it in case it is needed later.
Observable.create(new Observable.OnSubscribe<Application>() {
@Override
public void call(Subscriber<? super Application> subscriber) {
List result = getUserApps();
if (result != null){
for (Application app : result){
subscriber.onNext(app);
}
subscriber.onComplete();
}else{
subscriber.onError(new IOException("no permission / no internet / etc"));
//or if this is a try catch event you can pass the exception
}
}
})
.subscribeOn(Schedulers.io())//the thread *observer* runs in
.observeOn(AndroidSchedulers.mainThread())//the thread *subscriber* runs in
.map(new Func1<Application, String>() {
// Mapping methods are where data are manipulated.
// You can simply skip this and
//do the same thing in Subscriber implementation
@Override
public String call(Application application) {
return application.getName();
}
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
Toast.makeText(context, "completed", Toast.LENGTH_SHORT).show();
//because subscriber runs in main UI thread it's ok to do UI stuff
//raise Toast, play sound, etc
}
@Override
public void onError(Throwable e) {
Log.e("getAppsError", e.getMessage());
//raise Toast, play sound, etc
}
@Override
public void onNext(String s) {
listAdapter.add(s);
}
});
Here is the newbie response (because I am new in javarx and finally fix this issue) :
Here is your implementation :
Observable.create(new Observable.OnSubscribe<RegionItem>() {
@Override
public void call(Subscriber<? super RegionItem> subscriber) {
subscriber.onError(new Exception("TADA !"));
}
})
.doOnNext(actionNext)
.doOnError(actionError)
.doOnCompleted(actionCompleted)
.subscribe();
In this previous implementation, when I subscribe I trigger the error flow ... and I get an application crash.
The problem is that you HAVE TO manage the error from the subscribe() call. The "doOnError(...)" is just a kind of helper that clone the error and give you a new place to do some action after an error. But it doesn't Handle the error.
So you have to change your code with that :
Observable.create(new Observable.OnSubscribe<RegionItem>() {
@Override
public void call(Subscriber<? super RegionItem> subscriber) {
subscriber.onError(new Exception("TADA !"));
}
})
.subscribe(actionNext, actionError, actionCompleted);
Not sure about the real explanation, but this is how I fix it. Hope it will help.