我正在尝试学习一些RxJava和RxAndroid,我认为我遇到的问题可以很容易地使用这样的工具来解决。问题是:我们可以在一个活动中有“N”个视图,并且每个视图都用于满足某些条件。当用户按“保存”时,我们想检查所有视图中是否满足所有条件,如果不满足,请用户分别确认每个视图。所以这是我在没有RxJava的情况下如何处理这个问题的示例:
private void validation(List<CustomView> views)
{
for (CustomView view : views)
{
if (view.metCondition() == false)
{
showConfirmationDialog(view);
return false;
}
}
return true;
}
private void showConfirmationDialog(CustomView view)
{
ConfirmationDialog dialog = new ConfirmationDialog(this, view);
dialog.show();
}
private void dialogResult(CustomView view)
{
view.setCondition(true);
validation(mViews);
}
显然,我需要某种类型的监听器来确认结果,并且在条件被确认后(使用OK或Cancel),将“view.metCondition()”设置为true,这样就不会再次弹出此视图。当然,在“validation”返回true后,它将运行“Save()”函数。
这是我真正的解决方案,因为我想让它尽可能简单,所以如果您知道如何使用RxJava完成类似的事情,请发表评论。我已经在使用这个库来处理一些异步的东西(与usb连接的设备对话),所以我知道一些东西,但从来都不知道如何像这样链接调用。
非常感谢您的帮助。
编辑
添加了listener方法,这样我们就可以看到再次调用了“验证()”函数
只是一个灵感的例子:)
private static class CustomViewValidator {
//Subject can be attach to other sources eg. EditText etc
//Of course it can be replaced with simple variable
BehaviorSubject<Boolean> mSubject = BehaviorSubject.create();
Observable<Boolean> getValidationObservable() {
return mSubject.asObservable().map(s -> {
if (!s) {
throw new ViewValidationThrowable(CustomViewValidator.this);
} else {
return true;
}
});
}
void setCondition(boolean v) {
mSubject.onNext(v);
}
}
private static class ViewValidationThrowable extends RuntimeException {
//custom Exception let us to keep reference to invalid View
private final CustomViewValidator mView;
private ViewValidationThrowable(CustomViewValidator view) {
mView = view;
}
}
private List<CustomViewValidator> mViews;
private void validate(final List<CustomViewValidator> viewObservables) {
Observable.from(viewObservables)
.flatMap(CustomViewValidator::getValidationObservable)
.subscribe(aBoolean -> {
//we can just ignore all items
},
throwable -> {
if (throwable instanceof ViewValidationThrowable) {
CustomViewValidator view = ((ViewValidationThrowable) throwable).mView;
//show dialog here
}
},
() -> {
//everything valid
});
}
private void dialogResult(CustomViewValidator view) {
view.setCondition(true);
validate(mViews);
}
在本例中,我们仍然需要在每次需要进行验证时调用validate方法。
这是另一个我们不断链的例子。
private static class Pair<T,V> {
private final T first;
private final V second;
public Pair(T first, V second) {
this.first = first;
this.second = second;
}
}
private static class CustomViewValidator {
//Subject allows us:
// * probably not break chain later using some retry techniques
// * subject can be attach to other sources eg. EditText etc
//Of course it can be replaced with simple variable
BehaviorSubject<Boolean> mSubject = BehaviorSubject.create();
Observable<Pair<Boolean,CustomViewValidator>> getValidationObservable() {
return mSubject.asObservable().map(s -> new Pair<>(s,CustomViewValidator.this));
}
void setCondition(boolean v) {
mSubject.onNext(v);
}
}
private void validate(final List<Observable<Pair<Boolean, CustomViewValidator>>> viewObservables) {
//IMPORTANT do not forget to unsubscribe
// In this case we do not break our chain, so it can last forever
Subscription subsciption = Observable.combineLatest(viewObservables,
objects -> {
for (Object object : objects) {
Pair<Boolean, CustomViewValidator> viewPair = (Pair<Boolean, CustomViewValidator>) object;
if (!viewPair.first) {
return viewPair;
}
}
return new Pair<>(true, null);
})
.subscribe(pair -> {
if (pair.first) {
//everything is valid DO NOT USE second argument here
} else {
//show dialog here using pair.second as View
}
});
}
private void dialogResult(CustomViewValidator view) {
view.setCondition(true);
//no reason to call validate again
//setCondition will trigger chain again
}
对不起,我没有测试它。只是想告诉你不同方法的主要思想。这些方法在很大程度上基于公认答案中已经表达的想法。
对于链式验证,您真的应该查看combineLatest()
操作符。首先,为每个视图创建可观察的,然后使用该操作符。RxBinding是Android视图的一个优秀扩展。
看这个例子。这是一个很好的验证例子。
我在IO线程上有一个简单的工作,它正在改变主屏幕壁纸,之后我试图在UI线程上运行一些动画: 但这种方法会导致错误:<代码>java。lang.IllegalStateException:观察者必须从主UI线程订阅,但它是线程[RxCachedThreadScheduler-1,5,main] 我尝试将第二个可观察更改为: 但这于事无补。
我在Android上使用RxJava和Retrofit2.0来处理网络请求。 在创建可观察对象时,我向其添加以下内容: 是否有一个优雅的解决方案来解决这个问题,而不必手动地用一个块包装我的实现,以便将一些东西发布到主线程?
我正在开发利用RxJava、realm和改进的应用程序。 我需要创建非常具体的数据处理链。我需要在io调度程序上执行改装调用,然后在我的自定义单线程领域调度程序上处理提供的数据,然后将结果推送到主线程调度程序上的ui。我试图通过使用多个组合来实现这一点,包括观察(observeOn)和订阅(subscribeOn),但我无法让中间部分在调度程序(scheduler)上执行。 我的目标是这样的
我必须根据传入的请求写入文件。由于多个请求可能同时出现,我不希望多个线程试图一起覆盖文件内容,这可能会导致丢失一些数据。 因此,我尝试使用实例变量PublishSubject收集所有请求的数据。我在初始化期间订阅了publishSubject,此订阅将在应用程序的整个生命周期内保持不变。此外,我还在一个单独的线程(由Vertx事件循环提供)上观察到相同的实例,该线程调用负责编写文件的方法。 稍后在
我有以下代码: 第三方DK。doSomeAction回调在主线程上发布,因此发射器也将在主线程上发出,而不是在订阅线程上发出(如果我在flatMap中进一步进行一些网络交互,链将失败)。 如果我在第一个之后添加,它会切换到正确的线程,但是有没有办法在正确的线程上发出?我不能修改行为。
问题内容: 我正在Xcode 9 beta,iOS 11中使用Google Maps。 我收到如下错误输出到日志: 主线程检查器:在后台线程上调用的UI API:-[UIApplication applicationState] PID:4442,TID:837820,线程名称:com.google.Maps.LabelingBehavior,队列名称:com.apple.root.default