Android Retrofit + RxJava使用詳解

封面

1.Retrofit基本使用

首先來了解下Retrofit是什么,在官網(wǎng)中對于Retrofit的描述是這樣的:

A type-safe HTTP client for Android and Java.

適用于Android和Java的類型安全的HTTP客戶端。

可以理解成一個封裝好的網(wǎng)絡(luò)請求庫。

Retrofit GitHub地址

接下來學(xué)習(xí)一下Retrofit的基本使用方法:

在app根目錄的build.gradle文件中加入依賴:

compile 'com.squareup.retrofit2:retrofit:2.3.0'

創(chuàng)建實(shí)體類:

我們使用http://www.kuaidi100.com/query?type=yuantong&postid=11111111111 這個快遞接口來測試,根據(jù)返回?cái)?shù)據(jù)創(chuàng)建實(shí)體類,類名為PostInfo,在這里就不貼代碼了,可以在文末下載Demo查看代碼。

定義請求參數(shù)接口:

public interface RetrofitService {

    /**
     * 獲取快遞信息
     *
     * @param type   快遞類型
     * @param postid 快遞單號
     * @return Call<PostInfo>
     */
    @GET("query")
    Call<PostInfo> getPostInfo(@Query("type") String type, @Query("postid") String postid);
}

定義一個接口RetrofitService,和普通的接口類相同,在里面定義一個方法getPostInfo,可以看到這個方法使用了@GET("query")注解,代表這是一個GET請求,請求接口為query(完整請求地址中域名/到?之間的字段),方法返回值為Call<PostInfo>實(shí)體,這個稍后會用于具體的網(wǎng)絡(luò)請求,PostInfo就是我們剛剛定義的實(shí)體類。參數(shù)中也使用了注解@Query,用于拼接傳入的字段(type=yuantong&postid=11111111111)。

網(wǎng)絡(luò)請求:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://www.kuaidi100.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
        
RetrofitService service = retrofit.create(RetrofitService.class);
Call<PostInfo> call = service.getPostInfo("yuantong", "11111111111");
call.enqueue(new Callback<PostInfo>() {
    @Override
    public void onResponse(Call<PostInfo> call, Response<PostInfo> response) {
        Log.i("http返回:", response.body().toString() + "");
    }

    @Override
    public void onFailure(Call<PostInfo> call, Throwable t) {

    }
});

可以看到Retrofit使用了Builder模式,首先傳入baseUrl,由于返回的數(shù)據(jù)是json類型的,還需要添加轉(zhuǎn)換工廠類,這需要在build.gradle文件中加入依賴:

compile 'com.squareup.retrofit2:converter-gson:2.3.0'

然后調(diào)用Retrofit的create方法創(chuàng)建RetrofitService的實(shí)體類,得到實(shí)體類之后就可以調(diào)用其中的getPostInfo方法并傳入?yún)?shù),getPostInfo方法會返回一個Call實(shí)體類,接著調(diào)用Call的enqueue方法,傳入Callback回調(diào),重寫onResponse(請求成功回調(diào))和onFailure(請求失敗回調(diào))方法,response參數(shù)中包含了請求結(jié)果中的所有信息(body、code、headers等)。

OK,到這里Retrofit的基本用法就講完了,接下來我們來了解一下Retrofit的其他用法。

2.Retrofit更多用法

請求方法

在RetrofitService的getPostInfo方法中,我們使用了@GET注解,說明這是一個GET方法,當(dāng)然也可以寫成HTTP協(xié)議中的其他請求方法(比如POST、PUT、DELETE、HEAD等)。

請求參數(shù)

在getPostInfo方法的參數(shù)中使用了@Query注解,除此之外還可以使用@QueryMap、@Path、@Body、@FormUrlEncoded/@Field、@Multipart/@Part、@Header/@Headers。

  • @Query()
@GET("query")
Call<PostInfo> getPostInfo(@Query("type") String type, @Query("postid") String postid);

相當(dāng)于

@GET(query?type=type&postid=postid)
Call<PostInfo> getPostInfo(@Query("type") String type, @Query("postid") String postid);
  • @QueryMap

當(dāng)參數(shù)很多的時候可以使用Map集合:

@GET("query")
Call<Book> getSearchBook(@QueryMap Map<String, String> parameters);
  • @Path

用于替換url中的某些字段,當(dāng)url中字段不確定時可以使用:

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);

id可以為任意字段,需要和@Path("id")中的字段保持一致,如果需要請求參數(shù),也可以使用@Query拼接:

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
  • @Body

可以使用實(shí)體類作為請求體,Retrofit會幫我們自動轉(zhuǎn)換:

@POST("users/new")
Call<User> createUser(@Body User user);
  • @FormUrlEncoded/@Field

用于傳送表單數(shù)據(jù),注意在頭部需要加上@FormUrlEncoded,first_name代表key,first代表value:

@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
  • @Multipart/@Part

用于上傳文件:

@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
  • @Header/@Headers

用于設(shè)置請求頭:

@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)

也可以通過@Headers設(shè)置:

@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
@Headers({
    "Accept: application/vnd.github.v3.full+json",
    "User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);

轉(zhuǎn)換器

Retrofit支持的序列化庫:

  • Gson: com.squareup.retrofit2:converter-gson

  • Jackson: com.squareup.retrofit2:converter-jackson

  • Moshi: com.squareup.retrofit2:converter-moshi

  • Protobuf: com.squareup.retrofit2:converter-protobuf

  • Wire: com.squareup.retrofit2:converter-wire

  • Simple XML: com.squareup.retrofit2:converter-simplexml

  • Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars

3.Retrofit + RxJava結(jié)合使用

如果你對RxJava還不太了解,可以看下這篇文章《給 Android 開發(fā)者的 RxJava 詳解》。

首先在build.gradle文件中加入依賴:

compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
compile 'io.reactivex:rxandroid:1.2.1'

將RetrofitService類中g(shù)etPostInfo方法的返回值修改為Observable(被觀察者):

public interface RetrofitService {

    /**
     * 獲取快遞信息
     * Rx方式
     *
     * @param type   快遞類型
     * @param postid 快遞單號
     * @return Observable<PostInfo>
     */
    @GET("query")
    Observable<PostInfo> getPostInfoRx(@Query("type") String type, @Query("postid") String postid);
}

在創(chuàng)建Retrofit時添加RxJava支持:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://www.kuaidi100.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 支持RxJava
        .build();

獲取被觀察者:

RetrofitService service = retrofit.create(RetrofitService.class);
Observable<PostInfo> observable = service.getPostInfoRx("yuantong", "11111111111");

訂閱:

observable.subscribeOn(Schedulers.io()) // 在子線程中進(jìn)行Http訪問
        .observeOn(AndroidSchedulers.mainThread()) // UI線程處理返回接口
        .subscribe(new Observer<PostInfo>() { // 訂閱

            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(PostInfo postInfo) {
                Log.i("http返回:", postInfo.toString() + "");
            }
        });

在RxJava中,由于鏈?zhǔn)秸{(diào)用的影響,是被觀察者訂閱觀察者。

到這里Retrofit + RxJava結(jié)合使用就講完了,由于Retrofit、RxJava屬于同門師兄弟,結(jié)合使用還是很容易的。

4.Retrofit打印請求參數(shù)

Retrofit中無法打印請求參數(shù),由于Retrofit是基于OkHttp進(jìn)行封裝的,可以對OkHttp添加日志攔截器來打印請求參數(shù):

在build.gradle文件中加入依賴:

compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'

OkHttp添加攔截器:

public class RetrofitUtils {

    /**
     * 獲取OkHttpClient
     * 用于打印請求參數(shù)
     *
     * @return OkHttpClient
     */
    public static OkHttpClient getOkHttpClient() {
        // 日志顯示級別
        HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.BODY;
        // 新建log攔截器
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.i("Http請求參數(shù):", message);
            }
        });
        loggingInterceptor.setLevel(level);
        // 定制OkHttp
        OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
        // OkHttp進(jìn)行添加攔截器loggingInterceptor
        httpClientBuilder.addInterceptor(loggingInterceptor);
        return httpClientBuilder.build();
    }
}

將定制的OkHttpClient添加到Retrofit中:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(Constant.SERVER_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .client(RetrofitUtils.getOkHttpClient()) // 打印請求參數(shù)
        .build();

大功告成!

5.寫在最后

源碼已托管到GitHub上,歡迎Fork,覺得還不錯就Start一下吧!

GitHub傳送門

點(diǎn)擊下載源碼

歡迎同學(xué)們吐槽評論,如果你覺得本篇博客對你有用,那么就留個言或者點(diǎn)下喜歡吧(^-^)

在下篇文章中將會探討一下Retrofit封裝的最佳姿勢,敬請期待!

《Android 探討一下Retrofit封裝的最佳姿勢》

已修改為支持RxJava2,最新代碼已同步至GitHub。

compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,326評論 25 708
  • Retrofit 實(shí)際上并不能說是一個網(wǎng)絡(luò)請求框架,它其實(shí)是對 okHttp 這個網(wǎng)絡(luò)請求框架在接口層面的封裝,網(wǎng)...
    EmanLu閱讀 1,203評論 0 2
  • 前言 如果看Retrofit的源碼會發(fā)現(xiàn)其實(shí)質(zhì)上就是對okHttp的封裝,使用面向接口的方式進(jìn)行網(wǎng)絡(luò)請求,利用動態(tài)...
    李某人吖閱讀 2,254評論 0 0
  • “小莊子,依你看長孫平此次之行,結(jié)果該當(dāng)如何?”“皇上英明神武,運(yùn)籌帷幄,知人善任,決勝千里,莫說長孫大人是一代驍...
    颯颯秋風(fēng)爽why閱讀 378評論 0 2
  • 當(dāng)局者迷,旁觀者清!呵呵, 摩天輪的角度沒有找對 大霖一眼就看出來了 我卻畫過之后才看出來 明天重新來畫吧 哈哈,加油哦
    華姐手心里的溫柔閱讀 269評論 0 0

友情鏈接更多精彩內(nèi)容