使用RXJava和Retrofit进行网络调用正确实现 - Android

时间:2017-05-04 23:13:44

标签: android rx-java retrofit2 okhttp rx-android

我想对用户端点(注册新用户)进行简单的api调用,并获得带有响应的身份验证令牌。任何人都可以解释这两个网络调用之间的区别,在我的情况下哪个实现是正确的?

 private void registerProcess(User user) {
    mSubscriptions.add(Network.getRetrofit().getUserToken(user)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<Response<TokenResponse>>() {
                @Override
                public void call(Response<TokenResponse> tokenResponse) {
                    if (tokenResponse.code() == 200) {
                        mProgressbar.setVisibility(View.GONE);
                        showSnackBarMessage("Registration success!");
                    } else {
                        mProgressbar.setVisibility(View.GONE);
                        showSnackBarMessage("Registration failed");
                    }

                }
            }));

}

 private void registerProcess(User user) {

    Network.getRetrofit().getUserToken(user)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<Response<TokenResponse>>() {
                @Override
                public void onCompleted() {
                    /// what to do here???
                }

                @Override
                public void onError(Throwable e) {
                    mProgressbar.setVisibility(View.GONE);
                    showSnackBarMessage("Registration failed");
                }

                @Override
                public void onNext(Response<TokenResponse> tokenResponse) {
                  if (tokenResponse.code() == 200) {
                        mProgressbar.setVisibility(View.GONE);
                        showSnackBarMessage("Registration success!");
                    } 
                }
            });

}

1 个答案:

答案 0 :(得分:2)

第一种情况:

  • 没有onError回调处理,因此,例如,IOException会导致您的应用崩溃。

第二个:

  • 订阅不会存储在任何地方(与第一种情况不同),因此如果它仍然在运行而且未在活动的onDestroy回调中取消订阅,则会泄漏。
  • onNext仅处理成功的响应,因此如果存在与200不同的HTTP代码,则不会发生任何事情。

正确的实现是这两个片段的融合:

private void registerProcess(User user) {
    mSubscriptions.add(Network.getRetrofit().getUserToken(user)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<Response<TokenResponse>>() {
            @Override
            public void onCompleted() {
                // you might do nothing here
            }

            @Override
            public void onError(Throwable e) {
                mProgressbar.setVisibility(View.GONE);
                showSnackBarMessage("Error!");
            }

            @Override
            public void onNext(Response<TokenResponse> tokenResponse) {
                if (tokenResponse.code() == 200) {
                    mProgressbar.setVisibility(View.GONE);
                    showSnackBarMessage("Registration success!");
                } else {
                    mProgressbar.setVisibility(View.GONE);
                    showSnackBarMessage("Registration failed");
                } 
            }
        });
}

请勿忘记在销毁活动(或片段)时致电mSubscriptions.clear(),以取消订阅所有已存储的订阅。

P.S。您可以使用doOnSubscribedoAfterTerminate运算符来相应地设置初始和终端视图状态。例如,为了避免多次调用mProgressbar.setVisibility(View.GONE)

mSubscriptions.add(Network.getRetrofit().getUserToken(user)
    .doOnSubscribe(() -> mProgressbar.setVisibility(View.VISIBLE))
    .doAfterterminate(() -> mProgressbar.setVisibility(View.GONE))
    ...