Progress Dialog not showing up before RXJava call

老子叫甜甜 提交于 2019-12-13 18:56:54

问题


I have the following code, where I start a ring dialog before I make a long running task, done in RxJava2. The problem is that the dialog isn't showing up and I don't think I'm blocking the main UI thread.

  fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (ringProgressDialog != null) {
                if (ringProgressDialog.isShowing()) {
                    ringProgressDialog.dismiss();
                }
            }
            ringProgressDialog = ProgressDialog.show(SendConversationsActivity.this,
                    getResources().getString(R.string.creating_document_progress_dialog_title),
                    getResources().getString(R.string.conversation_progress_dialog_text),
                    true, false);
            FileNameAndContacts filenameAndContacts = new FileNameAndContacts();
            if (tvNoDatSelected.getVisibility() != View.VISIBLE) {
                filenameAndContacts.setFileName("");
            }
            createDocument(filenameAndContacts)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnError(throwable -> Timber.e(throwable, "Error in getting document"))
                    .subscribe(fileAndContacts -> {
                        if (ringProgressDialog.isShowing()) { //debugger says 
                                                              //dialog is showing. 
                            ringProgressDialog.dismiss();
                        }
                        sendDocumentInEmail(fileAndContacts);

                    });
     }

Task executes properly. I also show another ring progress dialog before I do another RXJava task in the same activity, this one shows up.

If I comment out the RxJava call, the dialog shows up. So something in the RxJava call is blocking.

//EDIT This simple observable also blocks the progress dialog from showing (but the Toast displays):

                Observable.just("Hello, world")
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnSubscribe(disposable -> {
                        Toast.makeText(SendConversationsActivity.this, "Toast...", Toast.LENGTH_SHORT).show();
                        //ringProgressDialog.show();
                    })
                    .doOnTerminate(() -> {
                        //ringProgressDialog.dismiss();
                    })
                    .subscribe(s -> {
                        //Toast.makeText(SendConversationsActivity.this, s, Toast.LENGTH_SHORT).show();
                        ringProgressDialog.dismiss();
                    });

回答1:


How is createDocument implemented? create, fromCallable

@akarnokd I do the calculations then do a Single.just(fileNameAndContacts)

As suspected, you compute the document on the current thread (main) and blocking it. You should move it into fromCallable and it will compute in the background when combined with subscribeOn(Schedulers.io()):

Observable.fromCallable(() -> {
     /* compute the document here */
    return fileNameAndContacts;
}); 



回答2:


I suggest doing RxAndroid2 in this way

// Init your dialog
ProgressDialog ringProgressDialog = new ProgressDialog(this);
ringProgressDialog.setTitle("Your Title");
ringProgressDialog.setMessage("Your message");

createDocument(filenameAndContacts)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .doOnSubscribe(disposable -> ringProgressDialog.show())
        .doOnTerminate(() -> {
            if (ringProgressDialog.isShowing()) {
                ringProgressDialog.dismiss();
            }
        })
        .concatMap(fileAndContacts -> sendDocumentInEmail(fileAndContacts))
        .subscribe(this::onSuccess, this::onError)


private void onSuccess() {
    // Do anything you want on Android main thread
}

private void onError() {
    // Timber..
}

Explanation

The method doOnSubscribe() will be called whenever your observable start to subscribe and doOnTerminate() will be called just before the resulting Observable terminates, whether normally or with an error.

Then, if you want to do another thing like sendDocumentInEmail after you get fileAndContacts, just use concatMap()

So, whenever error happens, you can handle it in onError() method.

Doing like this will help you avoid callback hell or side-effect, which easily lead you to error prone.

Reference:

  • http://reactivex.io/documentation/operators/do.html

  • https://fernandocejas.com/2015/01/11/rxjava-observable-tranformation-concatmap-vs-flatmap/

Hope this help



来源:https://stackoverflow.com/questions/45573892/progress-dialog-not-showing-up-before-rxjava-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!