关于RX Java:使用RXJava和Retrofit正确实现网络调用-Android

Network call with RXJava and Retrofit correct implementation - Android

我想对用户端点进行简单的api调用(注册一个新用户),并在响应中获取auth令牌。谁能解释这两个网络调用之间的区别?在我看来,哪种实现是正确的?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 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!");
                    }
                }
            });

}

第一种情况:

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

第二个:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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)

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