實際開發過程中一般都會選擇一些網絡框架提升開發效率。隨著Google對HttpClient 摒棄和Volley框架的逐漸沒落,OkHttp開始異軍突起,而Retrofit則對OkHttp進行了強制依賴,可以簡單理解Retroifit在OKHttp基礎上進一步完善。
Retrofit是由Square公司出品的針對于Android和java的類型安全的Http客戶端,目前推出了2.0+的版本。
Retrofit框架項目地址:https://github.com/square/retrofit。 Retrofit官方文檔地址: http://square.github.io/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'}我們以查號碼歸屬地接口為例 https://www.juhe.cn/docs/api/id/11
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-gsonJackson: com.squareup.retrofit:converter-jacksonMoshi: com.squareup.retrofit:converter-moshiProtobuf: com.squareup.retrofit:converter-protobufWire: com.squareup.retrofit:converter-wireSimple xml: com.squareup.retrofit:converter-simplexmlRetrofit需要把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都要抱下他的大腿,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
新聞熱點
疑難解答