RxJava onError Can't create handler inside thread that has not called Looper.prepare()

user1851366 picture user1851366 · Sep 5, 2016 · Viewed 8.8k times · Source

first i will try to explain what im trying to do, next you will see what im doing(code). Since im new at RxJava, and still learning fell free to give me your opinion.

So, im calling a network API from server and when start request i call loader(spinner), when finish i hide it and same when i get an error. I would like this generic for all my requests so i get Observable and Observer from parameter. On this method, i just care about hide and show loader.

OnError(and here is the trick part), im trying to show a dialog too, but i got the error that you can see on title. Can't create handler inside thread that has not called Looper.prepare()

Here is the code..

protected void makeMyrequest(MyBaseActivity myBaseActivity, Observable observable, Observer observer) {

    mSubscription = observable
            .doOnRequest(new Action1<Long>() {
                @Override
                public void call(Long aLong) {

                    Log.d(TAG, "On request");
                    myBaseActivity.showLoader();
                }
            })
            .doOnCompleted(new Action0() {
                @Override
                public void call() {
                    Log.d(TAG, "onCompleted: Hide spinner");
                    myBaseActivity.hideLoader();
                    mSubscription.unsubscribe();
                }
            })
            .doOnError(new Action1<Throwable>() {
                @Override
                public void call(Throwable throwable) {

                    Log.d(TAG, "onError: Hide spinner");
                        myBaseActivity.showAlertDialog("error");
                        myBaseActivity.hideLoader();

                                        }
            })
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(observer);
}

On my base activity i have a method to show dialog

public void showAlertDialog(String message) {

    mDialog = new AlertDialog.Builder(this)
            .setMessage(message)
            .show();
}

The part that matters from stacktracer

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
                                                                                at android.os.Handler.<init>(Handler.java:200)
                                                                                at android.os.Handler.<init>(Handler.java:114)
                                                                                at android.app.Dialog.<init>(Dialog.java:119)
                                                                                at android.app.Dialog.<init>(Dialog.java:168)
                                                                                at android.support.v7.app.AppCompatDialog.<init>(AppCompatDialog.java:43)
                                                                                at android.support.v7.app.AlertDialog.<init>(AlertDialog.java:95)
                                                                                at android.support.v7.app.AlertDialog$Builder.create(AlertDialog.java:927)
                                                                                at android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:952)
                                                                                at xx.myapp.MyBaseActivity.showAlertDialog

Answer

Geralt_Encore picture Geralt_Encore · Sep 5, 2016

You need to call observeOn(AndroidSchedulers.mainThread()) before doOnRequest. observeOn applies to all operators after him on a chain of calls. In your case exception raised because you are trying to create a dialog outside of main thread.