美文网首页
Retrofit学习笔记

Retrofit学习笔记

作者: heyzhuyue | 来源:发表于2017-05-11 15:29 被阅读8次

    一、Retrofit简介

    Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现

    Retrofit执行网络请求

    以一个GET请求为例,执行网路请求所需步骤:

    1.创建业务请求接口

    public interface BlueService {
        @GET("book/search")
        Call<BookSearchResponse> getSearchBooks(@Query("q") String name, 
                @Query("tag") String tag, @Query("start") int start, 
                @Query("count") int count);
    }
    

    2.需要创建一个Retrofit的示例,并完成相应的配置

    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.douban.com/v2/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
    
    BlueService service = retrofit.create(BlueService.class);
    

    baseUrl就是网络请求URL相对固定的地址,一般包括请求协议(如Http)、域名或IP地址、端口号等,当然还会有很多其他的配置,下文会详细介绍。addConverterFactory方法表示需要用什么转换器来解析返回值,GsonConverterFactory.create()表示调用Gson库来解析json返回值

    3.调用请求方法,并得到Call实例

    • 同步请求

      BookSearchResponse response = call.execute().body();
      

      网络请求一定要在子线程中完成,不能直接在UI线程执行,不然会crash

    • 异步请求

      call.enqueue(new Callback<BookSearchResponse>() {
        @Override
        public void onResponse(Call<BookSearchResponse> call,       Response<BookSearchResponse> response) {
            asyncText.setText("异步请求结果: " + response.body().books.get(0).altTitle);
        }
        @Override
        public void onFailure(Call<BookSearchResponse> call, Throwable t) {
      
        }
      });
      

    二、使用

    首先需要在module的build.gradle文件中依赖相关包,配置如下

    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
    

    引入这些包后,接下来需要对不同请求方式进行说明

    Get方法


    1. @Query

      Get方法请求参数都会以key=value的方式拼接在url后面,Retrofit提供了两种方式设置请求参数。第一种就是像上文提到的直接在interface中添加@Query注解,还有一种方式是通过Interceptor实现,直接看如何通过Interceptor实现请求参数的添加。

      public class CustomInterceptor implements Interceptor {
          @Override
          public Response intercept(Chain chain) throws IOException {
              Request request = chain.request();
              HttpUrl httpUrl = request.url().newBuilder()
                      .addQueryParameter("token", "tokenValue")
                      .build();
              request = request.newBuilder().url(httpUrl).build();
              return chain.proceed(request);
          }
      }
      

      ddQueryParameter就是添加请求参数的具体代码,这种方式比较适用于所有的请求都需要添加的参数,一般现在的网络请求都会添加token作为用户标识,那么这种方式就比较适合。

      创建完成自定义的Interceptor后,还需要在Retrofit创建client处完成添加

      addInterceptor(new CustomInterceptor())
      
    2. @QueryMap

      如果Query参数比较多,那么可以通过@QueryMap方式将所有的参数集成在一个Map统一传递

      public interface BlueService {
          @GET("book/search")
          Call<BookSearchResponse> getSearchBooks(@QueryMap Map<String, String> options);
      }
      
    3. Query集合

      假如你需要添加相同Key值,但是value却有多个的情况,一种方式是添加多个@Query参数,还有一种简便的方式是将所有的value放置在列表中,然后在同一个@Query下完成添加,实例代码如下:

      public interface BlueService {
          @GET("book/search")
          Call<BookSearchResponse> getSearchBooks(@Query("q") List<String> name);
      }
      
    4. @Path

      如果请求的相对地址也是需要调用方传递,那么可以使用@Path注解,示例代码如下:

      @GET("book/{id}")
      Call<BookResponse> getBook(@Path("id") String id);
      

    Post请求


    1. @field

      Post请求需要把请求参数放置在请求体中,而非拼接在url后面,先来看一个简单的例子

      @FormUrlEncoded
      @POST("book/reviews")
      Call<String> addReviews(@Field("book") String bookId, @Field("title") String title,
      @Field("content") String content, @Field("rating") String rating);
      

      特别说明:

    • @FormUrlEncoded将会自动将请求参数的类型调整为application/x-www-form-urlencoded,假如content传递的参数为Good Luck,那么最后得到的请求体就是

      FormUrlEncoded不能用于Get请求

    • @Field注解将每一个请求参数都存放至请求体中,还可以添加encoded参数,该参数为boolean型,具体的用法为

      @Field(value = "book", encoded = true) String book
      

      encoded参数为true的话,key-value-pair将会被编码,即将中文和特殊字符进行编码转换

    2.@FieldMap

    Post请求存在多个请求参数时,就可以使用FieldMap,使用方式如下:

    @FormUrlEncoded
    @POST("book/reviews")
    Call<String> addReviews(@FieldMap Map<String, String> fields);
    
    1. @Body

      Post请求参数有多个,统一封装到类中应该会更好,这样维护起来会非常方便

      @FormUrlEncoded
      @POST("book/reviews")
      Call<String> addReviews(@Body Reviews reviews);
      
      public class Reviews {
          public String book;
          public String title;
          public String content;
          public String rating;
      }
      

    相关文章

      网友评论

          本文标题:Retrofit学习笔记

          本文链接:https://www.haomeiwen.com/subject/cpbotxtx.html