本文使用登錄場景來簡單介紹 Android 應用中使用 OkHttp + Retrofit + RxJava 訪問網絡的用法厘惦。
- 數據交換協(xié)議 HTTP
- 數據交換格式 JSON
- HTTP 請求方法 POST
使用 HTTP 訪問網絡的準備工作鸵鸥,參見Android 訪問網絡:方案一 OkHttp一文訪問網絡的準備工作部分。
使用 OkHttp + Retrofit + RxJava 訪問網絡
1. 引入依賴
build.gradle(:app)
dependencies {
...
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.14.9'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.2'
}
2. 定義網絡訪問接口
創(chuàng)建 UserService 接口鸟雏,用來提供 User 模塊的網絡訪問服務。
UserService.java
public interface UserService {
@POST("user/login")
Single<Result<String>> login(@Body LoginParam loginParam);
}
Single
是 RxJava 中的一種可觀察對象類览祖。Retrofit 為我們創(chuàng)建該類的實例后孝鹊,即可調用 subscribe()
方法發(fā)起 HTTP 請求,然后在 SingleObserver
中處理請求結果展蒂。
有些關于 OkHttp + Retrofit + RxJava 的文章中在這里會使用 Observable
和 Observer
又活。
它們兩者的區(qū)別如下:
- Single 只發(fā)射一個值,或者一個錯誤通知锰悼。
- Observable 可以發(fā)射 0 或多個值和一個結束通知柳骄,或者一個錯誤通知。
HTTP 請求場景可能需要處理的結果有兩種:一是請求成功箕般,順利和服務端交換了數據耐薯;二是請求失敗。
如果把處理 HTTP 請求結果比作削蘋果丝里,那么使用 Single 類似于使用水果刀曲初;而 Observable 更像是使用菜刀。
總的來說丙者,Single 就像是為這個場景量身打造的复斥,而 Observable 則更加通用。都能勝任這個任務械媒,至于選擇目锭,就看個人喜好吧评汰。
關于 Result 類和方法注解的介紹,參見Android 訪問網絡:方案二 OkHttp + Retrofit一文的使用 OkHttp + Retrofit 訪問網絡-2.定義網絡訪問接口部分痢虹。
3. 創(chuàng)建 Retrofit 實例
- 創(chuàng)建 OkHttp 實例被去,添加日志攔截器,以便調試奖唯。
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.build();
- 創(chuàng)建 Retrofit 實例惨缆,配置 baseUrl , 添加 ConverterFactory 和 CallAdapterFactory 。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.43.218:8080/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.client(client)
.build();
4. 創(chuàng)建 Service 實例
UserService userService = retrofit.create(UserService.class);
5. 創(chuàng)建 Single 實例
Single<Result<String>> single = userService.login(new LoginParam(userName, password));
由于這一步比較簡單丰捷,通常的寫法是和下一步連起來坯墨,將 Single 的實例作為匿名對象來使用。
userService.login(new LoginParam(userName, password))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<Result<String>>() {...});
6. 向服務端發(fā)送 HTTP 請求
創(chuàng)建 SingleObserver 實例病往,用于處理網絡訪問結果捣染。
single.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new SingleObserver<Result<String>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onSuccess(@NonNull Result<String> result) {
}
@Override
public void onError(@NonNull Throwable e) {
}
});
-
subscribeOn(Schedulers.io())
在 IO 線程發(fā)送 HTTP 請求 -
observeOn(AndroidSchedulers.mainThread())
在主線程處理請求結果 -
onSubscribe()
當即將發(fā)送請求時調用 -
onSuccess()
當請求成功時調用 -
onError()
當請求失敗時調用
注:此處的成功和失敗是 HTTP 數據交換層面的意義。成功指的是 APP 和服務端順利交換了數據停巷。例如不論 APP 接收到的響應數據是{ "code": 600, "message": "登錄成功", "data": "token" }
還是{ "code": 701, "message": "密碼錯誤", "data": "" }
耍攘,都是請求成功,會執(zhí)行onSuccess()
方法畔勤。當無法和服務端交換數據時蕾各,則會執(zhí)行onError()
方法。
7. 在 SingleObserver 的 onSuccess() 中處理網絡訪問結果
@Override
public void onSuccess(@NonNull Result<String> result) {
Toast.makeText(LoginActivity.this, result.message, Toast.LENGTH_SHORT).show();
if (result.isSuccessful()) {
Log.i(TAG, "token : " + result.data);
// save token
// start activity
}
}
附
測試設備參數
- 型號:vivo Y66L
- 操作系統(tǒng):Funtouch OS 3.0(Android 6.0.1)