在 RXJava 调用之前未显示进度对话框
Progress Dialog not showing up before RXJava call
我有以下代码,在执行长 运行 任务之前,我在 RxJava2 中启动了一个环形对话框。问题是对话框没有显示,我认为我没有阻塞主线程 UI。
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);
});
}
任务正常执行。在同一 activity 中执行另一个 RXJava 任务之前,我还显示了另一个环形进度对话框,这个出现了。
如果我注释掉 RxJava 调用,对话框就会出现。所以 RxJava 调用中的某些东西是阻塞的。
//编辑
这个简单的 observable 也会阻止显示进度对话框(但会显示 Toast):
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();
});
我建议这样做RxAndroid2
// 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..
}
说明
方法 doOnSubscribe()
将在您的可观察对象开始订阅时被调用,并且 doOnTerminate()
将在结果 Observable
终止之前被调用,无论是正常终止还是错误终止。
然后,如果你想在得到fileAndContacts
之后做另一件事,比如sendDocumentInEmail
,只需使用concatMap()
因此,每当发生错误时,您都可以使用 onError()
方法进行处理。
这样做将帮助您避免回调地狱或副作用,这很容易导致您容易出错。
参考:
希望对您有所帮助
How is createDocument implemented? create, fromCallable
@akarnokd I do the calculations then do a Single.just(fileNameAndContacts)
正如所怀疑的那样,您在当前线程(主线程)上计算文档并阻止它。你应该把它移到 fromCallable
中,当与 subscribeOn(Schedulers.io())
:
结合时,它将在后台计算
Observable.fromCallable(() -> {
/* compute the document here */
return fileNameAndContacts;
});
我有以下代码,在执行长 运行 任务之前,我在 RxJava2 中启动了一个环形对话框。问题是对话框没有显示,我认为我没有阻塞主线程 UI。
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);
});
}
任务正常执行。在同一 activity 中执行另一个 RXJava 任务之前,我还显示了另一个环形进度对话框,这个出现了。
如果我注释掉 RxJava 调用,对话框就会出现。所以 RxJava 调用中的某些东西是阻塞的。
//编辑 这个简单的 observable 也会阻止显示进度对话框(但会显示 Toast):
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();
});
我建议这样做RxAndroid2
// 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..
}
说明
方法 doOnSubscribe()
将在您的可观察对象开始订阅时被调用,并且 doOnTerminate()
将在结果 Observable
终止之前被调用,无论是正常终止还是错误终止。
然后,如果你想在得到fileAndContacts
之后做另一件事,比如sendDocumentInEmail
,只需使用concatMap()
因此,每当发生错误时,您都可以使用 onError()
方法进行处理。
这样做将帮助您避免回调地狱或副作用,这很容易导致您容易出错。
参考:
希望对您有所帮助
How is createDocument implemented? create, fromCallable
@akarnokd I do the calculations then do a Single.just(fileNameAndContacts)
正如所怀疑的那样,您在当前线程(主线程)上计算文档并阻止它。你应该把它移到 fromCallable
中,当与 subscribeOn(Schedulers.io())
:
Observable.fromCallable(() -> {
/* compute the document here */
return fileNameAndContacts;
});