我有以下代码,在我执行长时间运行的任务之前,我在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);
});
}
任务正确执行。在我在同一个活动中执行另一个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();
});
答案 0 :(得分:4)
如何实施createDocument? create,fromCallable
@akarnokd我做计算然后做一个Single.just(fileNameAndContacts)
如怀疑的那样,您在当前线程(主)上计算文档并阻止它。您应将其移至fromCallable
,并在与subscribeOn(Schedulers.io())
结合使用后在后台进行计算:
Observable.fromCallable(() -> {
/* compute the document here */
return fileNameAndContacts;
});
答案 1 :(得分:3)
我建议用这种方式做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..
}
<强>解释强>
只要您的observable开始订阅,就会调用方法doOnSubscribe()
,并且在结果doOnTerminate()
终止之前调用Observable
,无论是正常还是错误。
然后,如果您想在获得sendDocumentInEmail
之后再做fileAndContacts
之类的其他事情,请使用concatMap()
因此,每当发生错误时,您都可以使用onError()
方法处理它。
这样做可以帮助你避免回调地狱或副作用,这很容易导致你容易出错。
参考:
希望这个帮助