Retrofit + RxJava+RxAndroid
阿新 • • 發佈:2019-01-12
一、背景
經常看到專案用Retrofit+RxJava+RxAndroid的框架,為了看懂專案的結構。現在來了解一下,Retrofit: Retrofit是Square 公司開發的一款正對Android 網路請求的框架。底層基於OkHttp 實現,OkHttp 已經得到了google 官方的認可OkHttp: 也是Square 開源的網路請求庫
RxJava:RxJava 在 GitHub 主頁上的自我介紹是 “a library for composing asynchronous and event-based programs using observable sequences for the Java VM”(一個在 Java VM 上使用可觀測的序列來組成非同步的、基於事件的程式的庫)。這就是 RxJava ,概括得非常精準。總之就是讓非同步操作變得非常簡單。
各自的職責:Retrofit 負責請求的資料和請求的結果,使用介面的方式呈現,OkHttp 負責請求的過程,RxJava 負責非同步,各種執行緒之間的切換RxJava + Retrofit + okHttp 已成為當前Android 網路請求最流行的方式。
二、Retrofit 寫一個網路請求
1,首先,要使用Retrofit ,你肯定需要把它的包引入,在你的build.gradle檔案中新增如下配置:
compile 'com.squareup.retrofit2:retrofit:2.1.0'//retrofit
compile 'com.google.code.gson:gson:2.6.2' //Gson 庫
//下面兩個是RxJava 和RxAndroid
compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'//轉換器,請求結果轉換成Model
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'//配合Rxjava 使用
2,建立一個Retrofit 例項,並且完成相關的配置
public static final String BASE_URL = "https://api.douban.com/v2/movie/" ;
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
說明:配置了介面的baseUrl和一個converter,GsonConverterFactory 是預設提供的Gson 轉換器,Retrofit 也支援其他的一些轉換器,詳情請看官網
3,建立一個 介面 ,程式碼如下:
public interface MovieService {
//獲取豆瓣Top250 榜單
@GET("top250")
Call<MovieSubject> getTop250(@Query("start") int start,@Query("count")int count);
}
說明:定義了一個方法getTop250,使用get請求方式,加上@GET 標籤,標籤後面是這個介面的 尾址top250,完整的地址應該是 baseUrl+尾址 ,引數 使用@Query標籤,如果引數多的話可以用@QueryMap標籤,接收一個Map
4,用Retrofit 建立 介面例項 MoiveService,並且呼叫介面中的方法進行網路請求,程式碼如下:
//獲取介面例項
MovieService MovieService movieService = retrofit.create(MovieService.class);
//呼叫方法得到一個Call
Call<MovieSubject> call = movieService.getTop250(0,20);
//進行網路請求
call.enqueue(new Callback<MovieSubject>() {
@Override
public void onResponse(Call<MovieSubject> call, Response<MovieSubject> response) {
mMovieAdapter.setMovies(response.body().subjects);
mMovieAdapter.notifyDataSetChanged();
}
@Override
public void onFailure(Call<MovieSubject> call, Throwable t) {
t.printStackTrace();
}
});
以上示例是用get方式完成,如果要使用post 方式,我們只需要修改一下介面中的方法定義,如下:
public interface MovieService {
//獲取豆瓣Top250 榜單
@FormUrlEncoded
@POST("top250")
Call<MovieSubject> getTop250(@Field("start") int start, @Field("count") int count);
}
說明:使用POST 請求方式時,只需要更改方法定義的標籤,用@POST 標籤,引數標籤用 @Field 或者@Body或者FieldMap,注意:使用POST 方式時注意2點,1,必須加上 @FormUrlEncoded標籤,否則會拋異常。2,使用POST方式時,必須要有引數,否則會拋異常, 原始碼拋異常的地方如下:
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
以上就是一個使用Retrofit 完成一個網路請求的完整示例,其他標籤使用方式請看官網Retrofit官網,官網用法也介紹的比較詳細,此外,發現了一篇部落格也介紹得比較詳細,Retrofit用法詳解
三,配合RxJava 使用
1, 更改定義的介面,返回值不再是一個Call ,而是返回的一個Observble.
public interface MovieService {
//獲取豆瓣Top250 榜單
@GET("top250")
Observable<MovieSubject> getTop250(@Query("start") int start, @Query("count")int count);
}
2,建立Retrofit 的時候新增如下程式碼
addCallAdapterFactory(RxJavaCallAdapterFactory.create())
3,新增轉換器Converter(將json 轉為JavaBean)
addConverterFactory(GsonConverterFactory.create())
4,Activity 或者 Fragment 中傳入 Subscriber 建立訂閱關係
Subscription subscription = movieService.getTop250(0,20)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<MovieSubject>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(MovieSubject movieSubject) {
mMovieAdapter.setMovies(movieSubject.subjects);
mMovieAdapter.notifyDataSetChanged();
}
});
以上是加入RxJava 後的網路請求,返回不再是一個Call ,而是一個Observable, 在Activity / Fragment 中傳入一個Subscriber 建立訂閱關係,就可以在 onNext 中處理結果了,RxJava 的好處是幫我處理執行緒之間的切換,我們可以在指定訂閱的在哪個執行緒,觀察在哪個執行緒。我們可以通過操作符進行資料變換。整個過程都是鏈式的,簡化邏輯。其中FlatMap 操作符 還可以解除多層巢狀的問題。總之,RxJava 很強大,能幫我處理很多複雜的場景,如果熟練使用的話,那麼能提升我們的開發效率。