Android Retrofit2 使用教程

什麼是 Retrofit ?

Retrofit是Square開發的一個Android和Java的REST客戶端庫。這個庫非常簡單並且具有很多特性,相比其他的網絡庫,更容易讓初學者快速掌握。它可以處理GET、POST、PUT、DELETE…等請求,還可以使用picasso加載圖片。

常用註解

Retrofit 2.0底層依賴OkHttp實現,也就是說Retrofit本質上就是對OkHttp的更進一步封裝。Retrofit和其它Http庫最大區別在於通過大範圍使用註解簡化Http請求。

Retrofit使用註解來描述HTTP請求: 
- URL參數的替換和query參數的支持 
- 對象轉化爲請求體(如:JSON,protocol buffers等) 
- 多重請求體和文件上傳

Retrofit中的註解大體分爲以下幾類:用於標註請求方式的註解、用於標記請求頭的註解、用於標記請求參數的註解。其實,任何一種Http庫都提供了相關的支持,無非在retrofit中是用註解來簡化。

請求方法註解

該類型的註解用於標註不同的http請求方式,主要有以下幾種:

註解 說明
@GET 表明這是get請求
@POST 表明這是post請求
@PUT 表明這是put請求
@DELETE 表明這是delete請求
@PATCH 表明這是一個patch請求,該請求是對put請求的補充,用於更新局部資源
@HEAD 表明這是一個head請求
@OPTIONS 表明這是一個option請求
@HTTP 通用註解,可以替換以上所有的註解,其擁有三個屬性:method,path,hasBody

 簡單用例:

@GET("mobile/capture")
Call<ResponseBody> getCapture(@Query("phone") String phone);

請求頭註解

該類型的註解用於爲請求添加請求頭。

註解 說明
@Headers 用於添加固定請求頭,可以同時添加多個。通過該註解添加的請求頭不會相互覆蓋,而是共同存在
@Header 作爲方法的參數傳入,用於添加不固定值的Header,該註解會更新已有的請求頭

@Headers的示例:

//使用@Headers添加單個請求頭
@Headers("Cache-Control:public,max-age=120")
@GET("mobile/active")
Call<ResponseBody> getActive(@Query("id") int activeId);

//使用@Headers添加多個請求頭
@Headers({
    "User-Agent:android"
    "Cache-Control:public,max-age=120",
    })
@GET("mobile/active")
Call<ResponseBody> getActive(@Query("id") int activeId);

 @Header的示例:

@GET("mobile/active")
Call<ResponseBody> getActive(@Header("token") String token,@Query("id") int activeId);

可以看出@Header是以方法參數形勢傳入的 

請求和響應格式註解

該類型的註解用於標註請求和響應的格式。

名稱 說明
@FormUrlEncoded 表示請求發送編碼表單數據,每個鍵值對需要使用@Field註解
@Multipart 表示請求發送multipart數據,需要配合使用@Part
@Streaming 表示響應用字節流的形式返回.如果沒使用該註解,默認會把數據全部載入到內存中.該註解在在下載大文件的特別有用

請求參數類註解

該類型的註解用來標註請求參數的格式,有些需要結合上面請求和響應格式的註解一起使用。

名稱 說明
@Body 多用於post請求發送非表單數據,比如想要以post方式傳遞json格式數據
@Filed 多用於post請求中表單字段,Filed和FieldMap需要FormUrlEncoded結合使用
@FiledMap 和@Filed作用一致,用於不確定表單參數
@Part 用於表單字段,Part和PartMap與Multipart註解結合使用,適合文件上傳的情況
@PartMap 用於表單字段,默認接受的類型是Map

 

Retrofit2基本使用 

先定義一個接口

public interface PersonalProtocol {
    /**
     * 用戶信息
     * @param page
     * @return
     */
    @FormUrlEncoded
    @POST("user/personal_list_info")
    Call<Response<PersonalInfo>> getPersonalListInfo(@Field("cur_page") int page);
}

@FormUrlEncoded註解表示from表單,另外還有@Multipart等註解,如果接口不需要傳遞參數,那麼@FormUrlEncoded以及@Multipart需要去掉

現在看看Retrofit的使用

private void requestRetrofit(){
        Retrofit retrofit = new Retrofit.Builder().baseUrl("www.xxxx.com/").build();
        PersonalProtocol personalProtocol = retrofit.create(PersonalProtocol.class);
        Call<Response<PersonalInfo>> call = personalProtocol.getPersonalListInfo(12);
        call.enqueue(new Callback<Response<PersonalInfo>>() {
            @Override
            public void onResponse(Call<Response<PersonalInfo>> call, Response<Response<PersonalInfo>> response) {
                //數據請求成功
            }

            @Override
            public void onFailure(Call<Response<PersonalInfo>> call, Throwable t) {
                //數據請求失敗
            }
        });
    }

首先將域名傳入構造一個Retrofit,然後通過retrofit中的create方法傳入一個Java接口並得到一個PersonalProtocol(當然PersonalProtocol這個對象是經過處理了的,這個後面會講到)調用getPersonalListInfo(12)然後返回一個Call,最後這個Call調用了enqueue方法去異步請求http,這就是一個基本的Retrofit的網絡請求。Retrofit2Call接口的默認實現是OkHttpCall,它默認使用OkHttp3作爲底層http請求client

 

其實Retrofit還有很多方法,我們現在選兩個一起來看看:

 OkHttpClient okHttpClient = new OkHttpClient();
        Retrofit retrofit = new Retrofit.Builder().baseUrl("www.xxxx.com")
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create(buildGson()))
                .build();

addConverterFactory方法中使用了gson去解析json

 

此外,我們再來看看RxJava的使用:

 OkHttpClient okHttpClient = new OkHttpClient();
        Retrofit retrofit = new Retrofit.Builder().baseUrl("www.xxxx.com")
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create(buildGson()))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

addCallAdapterFactory方法中使用了RxJavaCallAdapterFactory,網絡請求也需要修改:

PersonalProtocol personalProtocol = retrofit.create(PersonalProtocol.class);
rx.Observable<PersonalInfo> observable  = personalProtocol.getPersonalListInfo(12);
      observable.subscribeOn(Schedulers.io()) 
                .observeOn(AndroidSchedulers.mainThread())//最後在主線程中執行
                .subscribe(new Subscriber<PersonalInfo>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        //請求失敗
                    }

                    @Override
                    public void onNext(PersonalInfo personalInfo) {
                        //請求成功
                    }
                });

同時PersonalProtocol接口也需要改變:

public interface PersonalProtocol {
    /**
     * 用戶信息
     * @param page
     * @return
     */
    @FormUrlEncoded
    @POST("user/personal_list_info")
    Observable<PersonalInfo> getPersonalListInfo(@Field("cur_page") int page);
//    Call<Response<PersonalInfo>> getPersonalListInfo(@Field("cur_page") int page);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章