Retrofit 2.0基於OKHttp更高效更快的網絡框架 以及自定義轉換器
阿新 • • 發佈:2018-08-27
讀取數據 index gson final resp adapter oid 簡單的 build
時間關系,本文就 Retrofit 2.0的簡單使用 做講解 至於原理以後有空再去分析
項目全面、簡單、易懂 地址:
關於Retrofit 2.0的簡單使用如下: https://gitee.com/bimingcong/MyRetrofit
private void initGet() { Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://v.juhe.cn/") .addConverterFactory(GsonConverterFactory.create()) .build(); GetService service= retrofit.create(GetService.class); final Call<GetBean> call = service.getString3("toutiao", "shehui", "d05b58fa6901ad9bed77a1ef08bd6ccb"); call.enqueue(new Callback<GetBean>() { @Override public void onResponse(Call<GetBean> call, Response<GetBean> response) {if (response.isSuccessful()) { GetBean = response.body(); } } @Override public void onFailure(Call<GetBean> call, Throwable t) { } }); }
其中的GetService是幹嘛的 裏邊的@query其實可以理解為get請求url ?後邊那一串參數的鍵值對
public interface GetService { //直接拼接,記得加問號 @GET("toutiao/index?type=shehui&key=d05b58fa6901ad9bed77a1ef08bd6ccb") Call<GetBean> getString(); //{name}可以最簡單的將其理解為路徑替換塊,用”{}”表示,與註解@path配合使用 ,為了解耦,參數name==toutiao @GET("{name}/index?type=shehui&key=d05b58fa6901ad9bed77a1ef08bd6ccb") Call<GetBean> getString2(@Path("name") String name); //對於@GET來說,參數信息是可以直接放在url中上傳的。那麽你馬上就反應過來了,這一樣也存在嚴重的耦合! //於是,就有了@query @GET("{name}/index") Call<GetBean> getString3(@Path("name") String name, @Query("type") String type , @Query("key") String key); //假設我要在參數中上傳10個參數呢?這意味著我要在方法中聲明10個@Query參數?當然不是! //Retrofit也考慮到了這點,所以針對於復雜的參數上傳,為我們準備了@QueryMap @GET("{name}/index") Call<GetBean> getString4(@Path("name") String name, @QueryMap HashMap<String, String> hashMap); //一般Get都沒有請求體,所以直接獲取接口網址即可 Url動態化 @GET() Observable<ResponseBody> getString5(@Url String url); }
針對Post請求 其中的@Field 其實可以理解為 post要提交的 參數鍵值對 其中還有單個文件 以及多個文件的上傳
public interface PostService { @FormUrlEncoded @POST("toutiao/index") Call<PostBean> postString(@Field("type") String type, @Field("key") String key); // Post表單提交-多個參數-@FieldMa @FormUrlEncoded @POST("toutiao/index") Call<PostBean> postString2(@FieldMap HashMap<String, String> params); // Post文件提交 ,每個鍵值對都需要用@Part註解鍵名字 //Multipart 支持文件上傳 @Multipart @POST("https://pan.baidu.com/disk/home?#/all?vmode=list&path=%2Fas") Call<TestBean> postFile(@Part("photo\";filename=\"test.png\"") RequestBody body); @Multipart @POST("xxxx") Call<TestBean> postFile2(@PartMap HashMap<String, RequestBody> bodyMap, @Field("token") String token); }
對應的例子如下:
//當我獲取數據成功後要做什麽處理 public interface OnSuccessListener { void onSuccess(Object o); void onFaile(); }
//提供一些方法去調用service實體類的方法,RequestBody上傳單個文件 public void uploadFile(RequestBody body, final OnSuccessListener listener) { Call<TestBean> call = mService.postFile(body); call.enqueue(new Callback<TestBean>() { @Override public void onResponse(Call<TestBean> call, Response<TestBean> response) { listener.onSuccess(response); } @Override public void onFailure(Call<TestBean> call, Throwable t) { listener.onFaile(); } }); }
轉換器:
至於自定義轉換器 就是 下邊這個參數
Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://v.juhe.cn/") .addConverterFactory(GsonConverterFactory.create()) .build();
比如我們只希望返回數據是String類型,我們需要自定義一個ConverterFactory
public class StringConverFactory extends Converter.Factory { public static StringConverFactory create() { return new StringConverFactory(); } @Override public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { Log.d("wyz", "讀取數據:responseBodyConverter" + type); if (type == String.class) {//此處的Type類型 我的理解是一開始Call對象參數定義的返回值類型 Log.d("wyz", "執行開始"); return StringResponseBodyConverter.INSTANCE; } return null; } @Nullable @Override public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { Log.d("wyz", "請求數據類型:" + type); if (type == NetRequest.class){ } return null; }
final class StringResponseBodyConverter implements Converter<ResponseBody, String> { public static final StringResponseBodyConverter INSTANCE =new StringResponseBodyConverter(); @Override public String convert(ResponseBody value) throws IOException { Log.d("wyz", "轉換開始:" + value); String s = value.string(); return s; }
最後將 ConvertFactory設置到Retrofit實例中就可以了
retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(getOkHttpClient()) .addConverterFactory(StringConverFactory.create())
日誌:
最後對於 紅色的部分是添加一個自定義的Client 此處主要是對相應級別的日誌去攔截
在retrofit2.0中是沒有日誌功能的。但是retrofit2.0中依賴OkHttp,所以也就能夠通過OkHttp中的interceptor來實現實際的底層的請求和響應日誌。在這裏我們需要修改上一個retrofit實例,為其自定自定義的OkHttpClient。代碼如下:
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(); httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(httpLoggingInterceptor) .build(); Retrofit retrofit = new Retrofit.Builder().addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(okHttpClient) .baseUrl("https://api.github.com/") .addConverterFactory(GsonConverterFactory.create()) .build();
需要添加依賴:
compile ‘com.squareup.okhttp3:logging-interceptor:3.1.2‘
效果:
更加詳細的Demo 可以去我的開源中國裏看 https://gitee.com/bimingcong/MyRetrofit
Retrofit 2.0基於OKHttp更高效更快的網絡框架 以及自定義轉換器