基于Retrofit+RxJava的APP网络请求技术

Okhttp3

依赖配置

  build.gradle添加依赖:

1
implementation 'com.squareup.okhttp3:okhttp:3.10.0'

网络配置

  添加res->xml->network-security-config.xml文件:

1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>

  在AndroidMainifest.xml中添加网络安全权限(一共2处)。

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
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.njtech.myokhttp3">

<!-- 网络授权 -->
<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

简单的界面设计

  activity_main.xml

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<androidx.constraintlayout.widget.Guideline
android:id="@+id/h30"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.3" />

<androidx.constraintlayout.widget.Guideline
android:id="@+id/v50"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />

<TextView
android:id="@+id/tv_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/bt_test_GET_Syn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="测试GET同步无参"
app:layout_constraintEnd_toStartOf="@+id/v50"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/bt_test_GET_ASyn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="测试GET异步无参"
app:layout_constraintEnd_toStartOf="@+id/v50"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bt_test_GET_Syn" />

<Button
android:id="@+id/bt_test_GET_ASyn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="测试GET异步有参"
app:layout_constraintEnd_toStartOf="@+id/v50"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bt_test_GET_ASyn" />

<Button
android:id="@+id/bt_test_POST_ASyn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="测试POST异步"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/v50"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

GET和POST测试

  MainActivity.java

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
// 不能用本地的127.0.0.1,需要用实际的IP地址
String url = "http://10.22.82.219:8080/";

private TextView tvInfo;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//隐藏状态栏
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
getWindow().setStatusBarColor(Color.TRANSPARENT);
setContentView(R.layout.activity_main);

// 初始化控件
Button btTestGETSyn = findViewById(R.id.bt_test_GET_Syn);
btTestGETSyn.setOnClickListener(this);

Button btTestGETASyn = findViewById(R.id.bt_test_GET_ASyn);
btTestGETASyn.setOnClickListener(this);

Button btTestGETASyn2 = findViewById(R.id.bt_test_GET_ASyn2);
btTestGETASyn2.setOnClickListener(this);

Button btTestPOSTASyn = findViewById(R.id.bt_test_POST_ASyn);
btTestPOSTASyn.setOnClickListener(this);

tvInfo = findViewById(R.id.tv_info);
}

@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.bt_test_GET_Syn:
testGETSyn();
break;
case R.id.bt_test_GET_ASyn:
testGETASyn();
break;
case R.id.bt_test_GET_ASyn2:
testGETASyn2();
break;
case R.id.bt_test_POST_ASyn:
testPOSTASyn();
break;
}
}

// 测试GET同步方法
private void testGETSyn() {
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder()
.url(url + "doctor-user/listAll")
.get() //默认就是GET请求,可以不写
.build();
final Call call = okHttpClient.newCall(request);

new Thread(new Runnable() {
@Override
public void run() {
try {
Response response = call.execute();
final String info = response.body().string();
// 主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
tvInfo.setText(info);
}
});

} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}

// 测试GET异步方法(无参)
private void testGETASyn() {
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder()
.url(url + "doctor-user/listAll")
.get()
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 主线程更新UI
runOnUiThread(new Runnable() {
@SuppressLint("SetTextI18n")
@Override
public void run() {
tvInfo.setText("Error");
}
});
}

@Override
public void onResponse(Call call, final Response response) throws IOException {
final String info = response.body().string();
// 主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
tvInfo.setText(info);
}
});
}
});
}

// 测试GET异步方法(有参)
private void testGETASyn2() {
String requestBody = "10001";

OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder()
.url(url + "doctor-user/get/byEmployeeId/" + requestBody)
.get()
.build();

okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 主线程更新UI
runOnUiThread(new Runnable() {
@SuppressLint("SetTextI18n")
@Override
public void run() {
tvInfo.setText("Error");
}
});
}

@Override
public void onResponse(Call call, Response response) throws IOException {
try {
// 数据解析
String info = response.body().string();
JSONObject jsonObject = null;
jsonObject = new JSONObject(info);
final String data = jsonObject.get("data").toString();
// 主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
tvInfo.setText(data);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}

// 测试异步POST
private void testPOSTASyn(){
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody requestBody = new FormBody.Builder()
.add("name", "陈修翔")
.add("gender", "男")
.build();

Request request = new Request.Builder()
.url(url + "doctor-user/update/byName")
.post(requestBody)
.build();

okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 主线程更新UI
runOnUiThread(new Runnable() {
@SuppressLint("SetTextI18n")
@Override
public void run() {
tvInfo.setText("Error");
}
});
}

@Override
public void onResponse(Call call, Response response) throws IOException {
try {
// 数据解析
String info = response.body().string();
System.out.println(info);
JSONObject jsonObject = null;
jsonObject = new JSONObject(info);
final String data = jsonObject.get("message").toString();
// 主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
tvInfo.setText(data);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}

}

  注:这里异步POST测试没有调通!

参考博客

Android Okhttp3基本使用

Retrofit+RxJava

Retrofit简介

  Retrofit是现下Android端开发非常流行的一款网络请求框架,它通过动态代理的方式将Java接口翻译成网络请求,通过OkHttp发送请求,并且其具备强大的可扩展性,支持各种数据格式的转换以及RxJava
  网络请求框架是一套提供给开发者使用的用于网络请求的API接口,Android网络请求一般是基于Http协议的,而Http协议属于应用层的协议,具体的数据传输需要依赖传输层的TCP协议,Android系统提供了Socket编程接口给开发者建立TCP请求,所以具体数据的发送需要依赖SocketHttp协议属于应用层的协议,它是用来规定数据的传输格式的,用于传输双方都能按照固定的格式解读数据;所以,一个网络请求框架至少要包含以下几个功能:

  1. 提供接口给开发者传入请求参数;
  2. 编写Socket代码,建立TCP
  3. 通过TCP连接,严格按照Http协议的格式将请求参数发送给服务端;
  4. 严格按照Http协议的格式解读服务端返回的数据;
  5. 提供相应的接口给开发者获得返回数据(一般是通过回调处理的)。

  上面五点是一个网络请求框架必须具备的功能,当然,一个好的网络请求框架还应该具备如下特点:

  1. 提供给开发者使用的API尽可能简单;
  2. 添加了对网络缓存的处理,避免不必要的请求;
  3. 具有较高的性能;
  4. 具有较高的可扩展性。

  我们常用的OkHttpHttpURLConnection等网络请求框架,其内部就会将开发者传入的请求参数按照Http协议的格式组织好,并通过TCP连接发送给服务端,在收到服务端返回数据后,又会按照Http协议去解读数据,并提供相应的API(一般是回调)给开发者获得数据。由于OkHttp属于比较底层的网络请求框架,开发者在使用时还是会比较复杂,于是RetrofitOkHttp进行了再度的封装,使得开发者在使用时更加的方便。

  App应用程序通过Retrofit请求网络,实际上是使用Retrofit接口层封装请求参数,之后由OkHttp完成后续的请求操作。在服务端返回数据之后,OkHttp将原始的结果交给RetrofitRetrofit根据用户的需求对结果进行解析。完成数据的转化(converterFactory),适配(callAdapterFactory),通过设计模式进行各种扩展。

使用Retrofit的七步骤

  1. 添加Retrofit依赖,网络权限
  2. 定义接收服务器返回数据的Bean
  3. 创建网络请求的接口,使用注解(动态代理,核心)
  4. builder模式创建Retrofit实例,convertercalladapter
  5. 创建接口实例,调用具体的网络请求
  6. call同步/异步网络请求
  7. 处理服务器返回的数据

Retrofit网络通信八步骤

  1. 创建Retrofit实例
  2. 定义网络请求接口,并为接口中的方法添加注解
  3. 通过动态代理生成网络请求对象
  4. 通过网络请求适配器将网络请求对象进行平台适配
  5. 通过网络请求执行器,发送网络请求(call)
  6. 通过数据解析器解析数据
  7. 通过回调执行器,切换线程
  8. 用户在主线程处理返回结果

依赖配置

  build.gradle添加依赖:

1
2
3
4
5
6
7
//请求网络
implementation 'com.squareup.retrofit2:retrofit:2.8.1'
implementation 'com.squareup.retrofit2:converter-gson:2.8.1'
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
//RxJava
implementation 'io.reactivex.rxjava2:rxjava:2.0.1'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'

网络配置

  参考上文Okhttp3网络配置。

GET和POST测试

实体类

DoctorInfo.java

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
public class DoctorInfo {
private Long id;
private String name;
private String gender;
private int age;
private String job;
private String department;
private int employeeId;
private String cardId;
private String fingerId;
private String password;
// 不能用date,要用String!否则会Json解析错误!
private String updateTime;
private String createTime;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getJob() {
return job;
}

public void setJob(String job) {
this.job = job;
}

public String getDepartment() {
return department;
}

public void setDepartment(String department) {
this.department = department;
}

public int getEmployeeId() {
return employeeId;
}

public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}

public String getCardId() {
return cardId;
}

public void setCardId(String cardId) {
this.cardId = cardId;
}

public String getFingerId() {
return fingerId;
}

public void setFingerId(String fingerId) {
this.fingerId = fingerId;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getUpdateTime() {
return updateTime;
}

public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}

public String getCreateTime() {
return createTime;
}

public void setCreateTime(String createTime) {
this.createTime = createTime;
}

// 需要重写toString()!
@Override
public String toString() {
return "DoctorInfo{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
", job='" + job + '\'' +
", department='" + department + '\'' +
", employeeId=" + employeeId +
", cardId='" + cardId + '\'' +
", fingerId='" + fingerId + '\'' +
", password='" + password + '\'' +
", updateTime='" + updateTime + '\'' +
", createTime='" + createTime + '\'' +
'}';
}
}

DoctorData.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class DoctorData{
// 要和后端字段保持一致!
private List<DoctorInfo> doctorUserList;

public List<DoctorInfo> getDoctorUserList() {
return doctorUserList;
}

public void setDoctorUserList(List<DoctorInfo> doctorUserList) {
this.doctorUserList = doctorUserList;
}

@Override
public String toString() {
return "DoctorData{" +
"doctorUserList=" + doctorUserList +
'}';
}
}

DoctorResponse.java

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
public class DoctorResponse {
private boolean success;
private int code;
private String message;
// 要和后端字段保持一致!
private DoctorData data;

public boolean isSuccess() {
return success;
}

public void setSuccess(boolean success) {
this.success = success;
}

public int getCode() {
return code;
}

public void setCode(int code) {
this.code = code;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public DoctorData getData() {
return data;
}

public void setData(DoctorData data) {
this.data = data;
}
}

  注1:所有字段必须要和后端字段保持一致!
  注2:需要重写实体类的toString()方法。
  注3:Date类型的字段要用String类型替换!否则会Json解析错误。

网络工具类

SeerService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface SeerService {
// 步骤1:创建 用于描述网络请求 的接口
// 注解里传入 网络请求 的部分URL地址
// Retrofit把网络请求的URL分成了两部分:一部分放在Retrofit对象里,另一部分放在网络请求接口里
// 如果接口里的url是一个完整的网址,那么放在Retrofit对象里的URL可以忽略
// 采用Observable<...>接口
// getAllDoctorInfo()是接受网络请求数据的方法
@GET("doctor-user/listAll")
Observable<DoctorResponse> getAllDoctorInfo();

@GET("doctor-user/get/byEmployeeId/{employee_id}")
Observable<DoctorResponse> getDoctorInfoByEmployeeId(@Path("employee_id") Integer employeeId);

@POST("/doctor-user/update/byName")
Observable<DoctorResponse> updateDoctorInfoByDoctorName(@Body DoctorInfo doctorInfo);
}

SeerServiceCreator.java

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
// 写成单例类,避免重复创建,浪费资源
public class SeerServiceCreator {
private static SeerServiceCreator instance;

private Retrofit retrofit;

private SeerServiceCreator(){
retrofit = new Retrofit.Builder()
.baseUrl(Constant.SEER_SERVER_IP) // 设置 网络请求 Url
.addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava
.build();
}

// 双检锁/双重校验锁
public static SeerServiceCreator getInstance(){
if (instance == null) {
synchronized (SeerServiceCreator.class){
if (instance == null) {
instance = new SeerServiceCreator();
}
}
}
return instance;
}

public <T> T create(Class<T> tClass) {
return retrofit.create(tClass);
}
}

MainActivity实现

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private TextView tvInfo;

// 步骤2:创建Retrofit对象
SeerServiceCreator seerServiceCreator = SeerServiceCreator.getInstance();
// 步骤3:创建 网络请求接口 的实例
SeerService seerService = seerServiceCreator.create(SeerService.class);

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//隐藏状态栏
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
getWindow().setStatusBarColor(Color.TRANSPARENT);
setContentView(R.layout.activity_main);

// 初始化控件
Button btTestGETASyn = findViewById(R.id.bt_test_GET_ASyn);
btTestGETASyn.setOnClickListener(this);

Button btTestGETASyn2 = findViewById(R.id.bt_test_GET_ASyn2);
btTestGETASyn2.setOnClickListener(this);

Button btTestPOSTASyn = findViewById(R.id.bt_test_POST_ASyn);
btTestPOSTASyn.setOnClickListener(this);

tvInfo = findViewById(R.id.tv_info);
}

@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.bt_test_GET_ASyn:
testGETASyn();
break;
case R.id.bt_test_GET_ASyn2:
testGETASyn2();
break;
case R.id.bt_test_POST_ASyn:
testPOSTASyn();
break;
}
}

private void testGETASyn() {
// 步骤4:采用Observable<...>形式 对 网络请求 进行封装
Observable<DoctorResponse> observable = seerService.getAllDoctorInfo();
// 步骤5:发送网络请求
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<DoctorResponse>() {
@Override
public void accept(DoctorResponse doctorResponse) throws Exception {
final List<DoctorInfo> doctorUserList = doctorResponse.getData().getDoctorUserList();
// 主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
tvInfo.setText(doctorUserList.toString());
}
});
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
// 主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
tvInfo.setText("Error");
}
});
}
});
}

private void testGETASyn2() {
// 步骤4:采用Observable<...>形式 对 网络请求 进行封装
Observable<DoctorResponse> observable = seerService.getDoctorInfoByEmployeeId(10001);
// 步骤5:发送网络请求
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<DoctorResponse>() {
@Override
public void accept(DoctorResponse doctorResponse) throws Exception {
final List<DoctorInfo> doctorUserList = doctorResponse.getData().getDoctorUserList();
// 主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
tvInfo.setText(doctorUserList.toString());
}
});
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {

// 主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
tvInfo.setText("Error2");
}
});
}
});
}

private void testPOSTASyn() {
// 步骤4:采用Observable<...>形式 对 网络请求 进行封装
DoctorInfo doctorInfo = new DoctorInfo();
doctorInfo.setName("陈修翔");
doctorInfo.setAge(28);
doctorInfo.setEmployeeId(10001);
Observable<DoctorResponse> observable = seerService.updateDoctorInfoByDoctorName(doctorInfo);
// 步骤5:发送网络请求
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<DoctorResponse>() {
@Override
public void accept(DoctorResponse doctorResponse) throws Exception {
final String message = doctorResponse.getMessage();
// 主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
tvInfo.setText(message);
}
});
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {

// 主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
tvInfo.setText("Error3");
}
});
}
});
}
}

  这里只是简单的逻辑测试,不能当成业务代码处理。

参考博客

Android:Retrofit 与 RxJava联合使用大合集
Retrofit原理分析
Retrofit分析面试总结

谢谢老板!
-------------本文结束感谢您的阅读给个五星好评吧~~-------------