【问题标题】:Network call with RXJava and Retrofit correct implementation - Android使用 RXJava 和 Retrofit 正确实现的网络调用 - Android
【发布时间】:2017-10-03 07:07:36
【问题描述】:

我想对用户端点进行一个简单的 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!");
                    } 
                }
            });

}

【问题讨论】:

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


    【解决方案1】:

    第一种情况:

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

    第二个:

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

    正确的实现是这两个sn-ps的融合:

    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. 您可以使用doOnSubscribe 和doAfterTerminate 运算符来相应地设置初始和终端视图状态。例如避免多次调用mProgressbar.setVisibility(View.GONE):

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

    【讨论】:

    • 感谢您的回答!
    • .subscribe(new Action1&lt;TokenResponse&gt;() { @Override public void call(TokenResponse response) { RegisterFragment.this.handleResponse(response); } }, new Action1&lt;Throwable&gt;() { @Override public void call(Throwable error) { RegisterFragment.this.handleError(error); } 可以吗?
    • 是的,当然。您将失去对onComplete 的处理。
    猜你喜欢
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2016-10-29
    • 2015-10-24
    • 2017-04-18
    • 1970-01-01
    • 2013-06-06
    相关资源
    最近更新 更多