1. 程式人生 > >Retrofit全攻略——基礎篇

Retrofit全攻略——基礎篇

實際開發過程中一般都會選擇一些網路框架提升開發效率。隨著Google對HttpClient 摒棄和Volley框架的逐漸沒落,OkHttp開始異軍突起,而Retrofit則對OkHttp進行了強制依賴,可以簡單理解Retroifit在OKHttp基礎上進一步完善。

Retrofit是由Square公司出品的針對於Android和Java的型別安全的Http客戶端,目前推出了2.0+的版本。

使用Retrofit

接下來我們來學習下如何使用Retrofit。
首先需要在app/build.gradle新增依賴。

dependencies {
    //...
    //retrofit
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
//如果用到gson解析 需要新增下面的依賴 compile 'com.squareup.retrofit2:converter-gson:2.1.0' }

Retrofit不能直接使用,需要進行初始化,在這裡建立NetWork.java

public class NetWork {
    private static Retrofit retrofit;

    /**返回Retrofit*/
    public static Retrofit getRetrofit(){
        if(retrofit==null){
            Retrofit.Builder builder = new
Retrofit.Builder();//建立Retrfit構建器 retrofit = builder.baseUrl("http://apis.juhe.cn/") //指定網路請求的baseUrl .addConverterFactory(GsonConverterFactory.create())//返回的資料通過Gson解析 .build(); } return retrofit; } }

Retrofit需要之地baseUrl,往往一個專案中有很多介面,介面都使用相同的伺服器地址,這時候可以把介面地址相同的部分抽取到baseUrl中,Retrofit擴充套件性極好,可以指定返回的資料通過Gson解析,前提你需要保證專案中有Gson框架和com.squareup.retrofit2:converter-gson:2.1.0的依賴。

除了通過Gson解析還可以使用其它的方式解析,需要的依賴也不同,有如下幾種:

  • Gson: com.squareup.retrofit:converter-gson
  • Jackson: com.squareup.retrofit:converter-jackson
  • Moshi: com.squareup.retrofit:converter-moshi
  • Protobuf: com.squareup.retrofit:converter-protobuf
  • Wire: com.squareup.retrofit:converter-wire
  • Simple XML: com.squareup.retrofit:converter-simplexml

Retrofit需要把Http的請求介面封裝到一個介面檔案中。

public interface NetInterface {
    //獲取號碼歸屬地,返回來型別是Bean, 需要兩個引數分別為phone何key
    @GET("mobile/get")
    Call<Bean> getAddress(@Query("phone") String phone, @Query("key") String key);
}

其中Bean是根據請求的結果建立的物件.

方法前新增@GET註解表示當前請求是Get方式請求,連結的地址是baseUrl+”mobile/get”,baseUrl在初始化Retrofit的時候指定了,拼到一起就是 http://apis.juhe.cn/mobile/get
對於 Retrofit 2.0中新的URL定義方式,這裡是我的建議:

  • baseUrl: 總是以 /結尾
  • url: 不要以 / 開頭

因為如果不是這種方式,拼裝後的結果和你期望的是不一樣的,詳情參考官方文件。

除了Get請求還有下面幾種請求方式

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

最後的HTTP通用註解寫法比較特殊,請求可以代替之前的請求。下面的寫法和之前的@GET效果是一樣的。

/**
 * method 表示請的方法,不區分大小寫
 * path表示路徑
 * hasBody表示是否有請求體
 */
@HTTP(method = "get",path = "mobile/get",hasBody = false)
Call<Bean> getAddress(@Query("phone") String phone, @Query("key") String key);

@Quert表示查詢引數,用於GET查詢,註解裡的字串是引數的key值,引數會自動拼裝到Url後面。
除了上面的註解,再給大家介紹幾種不同的註解。

常用的註解

@Url:使用全路徑複寫baseUrl,適用於非統一baseUrl的場景。示例程式碼:

@GET Call<ResponseBody> XXX(@Url String url);

@Streaming:用於下載大檔案。示例程式碼:

@Streaming @GET Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl);


//獲取資料的程式碼
ResponseBody body = response.body();
long fileSize = body.contentLength();
InputStream inputStream = body.byteStream();

@Path:URL佔位符,用於替換和動態更新,相應的引數必須使用相同的字串被@Path進行註釋

//實際請求地址會給句groupId的值發生變化--> http://baseurl/group/groupId/users
@GET("group/{id}/users") Call<List<User>> groupList(@Path("id") int groupId);

@QueryMap:查詢引數,和@Query類似,區別就是後面需要Map集合引數。示例程式碼:

Call<List<News>> getNews((@QueryMap(encoded=true) Map<String, String> options);

@Body:用於POST請求體,將例項物件根據轉換方式轉換為對應的json字串引數,這個轉化方式是GsonConverterFactory定義的。 示例程式碼:

@POST("add")
Call<List<User>> addUser(@Body User user);

@Field,@FieldMap:Post方式傳遞簡單的鍵值對,需要新增@FormUrlEncoded表示表單提交

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

@Part,@PartMap:用於POST檔案上傳,其中@Part MultipartBody.Part代表檔案,@Part(“key”) RequestBody代表引數,需要新增@Multipart表示支援檔案上傳的表單。

@Multipart
   @POST("upload")
   Call<ResponseBody> upload(@Part("description") RequestBody description,
                             @Part MultipartBody.Part file);

完成請求例項

瞭解了Retrofit,我們用Retrofit請求完成請求,Retrofit使用起來比較省事,核心程式碼如下所示:

//初始化Retrofit,載入介面
NetInterface netInterface = NetWork.getRetrofit().create(NetInterface.class);
//請求介面
netInterface.getAddress(editText.getText().toString(),"你的app key")
        .enqueue(new Callback<Bean>() {
            @Override
            public void onResponse(Call<Bean> call, Response<Bean> response) {
                //請求成功
                Bean bean = response.body();
                //...
            }

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

Retrofit會自動在子執行緒中進行網路請求,請求結束切換到主執行緒中,而且內部使用了執行緒池,對網路請求的快取控制的也非常到位,網路響應速度也是很快的,使用起來非常的爽!

RxJava和Retrofit結合

RxJava非常強大,就連Retrofit都要抱下他的大腿,Retrofit也可以用RxJava方式進行網路請求,只需要對上面的程式碼進行改造即可。

首先新增框架依賴。

dependencies {
  //...

    compile 'io.reactivex:rxandroid:1.2.1'
    compile 'io.reactivex:rxjava:1.1.6'

    compile 'com.google.code.gson:gson:2.8.0'

    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    //如果用到gson解析 需要新增下面的依賴
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    //Retrofit使用RxJava需要的依賴
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

}

修改Retrofit初始化的程式碼:

public class NetWork {
    private static Retrofit retrofit;

    /**返回Retrofit*/
    public static Retrofit getRetrofit(){
        if(retrofit==null){
            //建立Retrfit構建器
            Retrofit.Builder builder = new Retrofit.Builder();
            //指定網路請求的baseUrl
            retrofit = builder.baseUrl("http://apis.juhe.cn/")
                    //返回的資料通過Gson解析
                    .addConverterFactory(GsonConverterFactory.create())
                    //使用RxJava模式
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

上面程式碼我們通過,新增程式碼addCallAdapterFactory(RxJavaCallAdapterFactory.create())就變成了使用RxJava模式。

介面也需要修改,把方法的返回值型別由Call改成了RxJava中的Observable。

public interface NetInterface {
    //獲取號碼歸屬地,返回來型別是Bean, 需要兩個引數分別為phone何key
    @GET("mobile/get")
    Observable<Bean> getAddress(@Query("phone") String phone, @Query("key") String key);
}

接下來修改最終網路請求的程式碼,可以改成RxJava方式了。

  NetInterface netInterface = NetWork.getRetrofit().create(NetInterface.class);
    //RxJava方式
    netInterface.getAddress(editText.getText().toString(),"你的app key")
            .subscribeOn(Schedulers.io())//設定網路請求在子執行緒中
            .observeOn(AndroidSchedulers.mainThread())// 回撥在主執行緒中
            .subscribe(new Action1<Bean>() {
                @Override
                public void call(Bean bean) {
                    //請求成功
                }
            }, new Action1<Throwable>() {
                @Override
                public void call(Throwable throwable) {
                    //請求失敗
                }
            });

總結

這是Retrofit基礎篇, 後面有時間再繼續深入研究

更多精彩請關注微信公眾賬號likeDev
這裡寫圖片描述