標籤:ini parameter lis 效果 nfa 請求 tar res 問號
時間關係,本文就 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表單提交-多個參數[email protected] @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更高效更快的網路架構 以及自訂轉換器