【问题标题】:Start activity inside a Rx Subscriber在 Rx 订阅者中启动活动
【发布时间】:2016-06-10 00:55:26
【问题描述】:

当我收到来自后端的响应时,我们正在尝试处理错误。如果响应成功,我们开始一个新的活动,另一方面,如果响应不成功,我们调用 onError 方法。

我们感觉我们没有正确处理生命周期,因为我们打开了一个新活动,我们的订阅被取消订阅,所以我们没有正确关闭对话框。我们是否应该在订阅者内部类中存储一个变量以在 onComplete 中请求该变量,并在该方法中启动新活动?或者这个近似值就足够了?

Subscriber<BackendResponse> subscriber = new Subscriber<BackendResponse>() {
        @Override
        public void onCompleted() {
            progressDialog.dismiss();
        }

        @Override
        public void onError(Throwable exception) {
            progressDialog.dismiss();
            SnackbarNotification.show(coordinatorLayout, "Error");
        }

        @Override
        public void onNext(BackendResponse backendResponse) {
            if (backendResponse.getSuccess()){
                startActivity(new Intent(LoginActivity.this, HomeActivity.class));
            } else {
                onError(new Exception("Launch onError"));
            }
        }
    };

此外,我们是否以正确的方式处理 onError 流程?我们知道从 onNext 调用 onError 将导致调用 Error 并在调用 onComplete 之后调用。我们应该取消订阅 onError 方法的订阅者吗?

我们为订阅者找到了一个包装器:

public abstract class DefaultSubscriber<T> extends Subscriber<T> {
    protected T result;

    @Override
    public void onCompleted() {
        onSuccess(result);
    }

    @Override
    public void onError(Throwable e) {
        CustomLog.e("onError", e.getMessage());
        onFailure(e);
    }

    @Override
    public void onNext(T t) {
        result = t;
    }

    protected abstract void onSuccess(T t);

    protected abstract void onFailure(Throwable exception);
}

这样做,我们将 onNext 提供的结果存储在成员变量中。一旦流完成(只有一次迭代),我们在 onCompleted 内部调用 onSuccess(结果)。另一方面,我们在 onFailure 方法中处理 onError。你怎么看?我们错过了什么吗?

【问题讨论】:

    标签: android rx-java reactive-programming rx-android


    【解决方案1】:

    首先我不会在订阅者中检查backendResponse.getSuccess()。我宁愿在它之前添加一个步骤,例如与.flatMap 类似:

    //your observable
    .flatMap(backendResponse - > {
       if (backendResponse.getSuccess()){
         return just(backendResponse);
       }else{
         return Observable.error(new Exception("Launch onError"));
       }
    })
    

    此外,我想订阅:

    .flatMap (  ...  ) // the flatmap above
    .subscribe(new Subscriber<BackendResponse>() {
            @Override
            public void onCompleted() {
            }
    
            @Override
            public void onError(Throwable exception) {
                progressDialog.dismiss();
                SnackbarNotification.show(coordinatorLayout, "Error");
            }
    
            @Override
            public void onNext(BackendResponse backendResponse) {
                progressDialog.dismiss();
                startActivity(new Intent(LoginActivity.this, HomeActivity.class));
            }
        });
    

    这会造成故障还是您想要的?我假设您只会收到一个BackendResponse 事件。

    但是,如果您只需要在 observable 完成时保留您的逻辑,那么我会看到两种解决方案:

    • 在 HomeActivity 中移动进度对话框逻辑
    • 延长订阅的生命周期(注意不要泄露订阅)

    【讨论】:

      猜你喜欢
      • 2010-10-09
      • 2018-02-06
      • 2011-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多