Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJava runs on same blocking UI Thread and doesn't show AlertDialog

I'm trying to use RxJava to show a AlertDialog during loading of some method. It doesn't work, UI is blocked for 2 seconds and when stepping through it with Debugger, the debugger shows that it is run on the UI thread. I've added the Schedulers.IO, so what am I doing wrong?

boolean initialize() {
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
    }
    return true;
}

public AlertDialog showSomePopup(Context context, String msg) {
    return new AlertDialog.Builder(context)
            .setTitle("Loading...")
            .setMessage(msg)
            .setPositiveButton("Ok", null)
            .show();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final AlertDialog dialog = showSomePopup(this, "Waiting ..");

    Single.just(initialize())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Boolean>() {
        @Override
        public void accept(@NonNull Boolean aBoolean) throws Exception {
            dialog.dismiss();
        }
    });
}
like image 599
Jim Clermonts Avatar asked Sep 16 '26 22:09

Jim Clermonts


2 Answers

The problem is that the .subscribe() is not being called until the initialize() method doesn't emit (i.e. as you're using .just(), until initialize() doesn't return.

like image 100
Xavier Rubio Jansana Avatar answered Sep 19 '26 11:09

Xavier Rubio Jansana


Your initialize function should return an Observable that the caller can subscribe to. In your case, you start the sequence by calling initialize() and then waiting for the result to return. What you should do:

Single<Boolean> initialize() {
    return Single.fromCallable(new Callable<Boolean>() {
       @Override
        public Boolean call() throws Exception {
            try {
                Thread.sleep(2000);
                return true;
            } catch (Exception ex) {
                return false;
            }
        }
    });
}

Now you can just put in the code that you had like this:

initialize()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Consumer<Boolean>() {
        @Override
        public void accept(@io.reactivex.annotations.NonNull Boolean aBoolean) throws Exception {
            if(aBoolean == true) {
                dialog.dismiss();
            }
        }
    });

and it will work as you wanted it to.

like image 22
Florian Hansen Avatar answered Sep 19 '26 10:09

Florian Hansen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!