Retrofit 2.x

导入依赖

compile ‘com.squareup.retrofit2:retrofit:2.2.0’
compile ‘com.squareup.retrofit2:converter-gson:2.2.0’
compile ‘com.squareup.retrofit2:adapter-rxjava:2.0.2’
compile ‘com.squareup.okhttp3:logging-interceptor:3.6.0’

常用注解:

一,@GET,@POST
  • get方式请求静态url

      //无参数
      @GET("API/public")
      Call getData;
    
      //只有一个参数且参数key值:uid
      @GET("API/public")
      Call getData(@Query("uid") String uid);
    
      //参数较多
      @GET("API/public")
      Call getData(@QueryMap Map params);
  • get方式请求动态url

    @GET
    Call getDataUrl(@Url String url);
  • post方式请求静态url

      //无参数
      @POST("API/public")
      Call postData();
    
      //一个参数
      @FormUrlEncoded
      @POST("API/public")
      Call postData(@Field("uid") String uid);
    
      //参数较多
      @FormUrlEncoded
      @POST("API/public")
      Call postData(@FieldMap Map params);
  • post方式请求动态url
    @POST
    Call postDataUrl(@Url String url);
小结
  • @Field@FieldMap用于Post方式传递简单的键值对,需要添加@FormUrlEncoded表示表单提交。

    • 如果在post请求中使用@Field和@FieldMap时去掉@FromUrlEncoded,那么程序会抛出java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1)的错误异常。

    • 如果将@FromUrlEncoded添加在@GET上面,同样的也会抛出
      java.lang.IllegalArgumentException:FormUrlEncoded can only be specified on HTTP methods with request body (e.g., @POST).的错误异常。

  • @Url:使用全路径复写baseUrl,适用于非统一baseUrl的场景,意思是当@GET或@POST注解的url为全路径时(如果和baseUrl不是一个域),会直接使用注解的url的域。

  • 如果请求为@POST,最好传递参数时使用@Field、@FieldMap和@FormUrlEncoded。因为@Query和@QueryMap都是将参数拼接在url后面的,而@Field或@FieldMap传递的参数时放在请求体的。

二,@Path
  • @Path:URL占位符,用于替换和动态更新,相应的参数必须使用相同的字符串被@Path进行注释
    @GET("group/{id}/users")
    Call groupList(@Path("id") int id);
小结
  • 使用@Path时,path对应的路径中不能包含”/”,否则会将其转化为%2F。如果动态设置url时使用@Url。
    @Url:使用全路径复写baseUrl,适用于非统一baseUrl的场景。
    @GET
    Call getData(@Url String url);
三,@Streaming
  • 用于下载大文件
  • @Streaming
    @GET
    Call downloadFile(@Url String fileUrl);
四,@Body
  • @Body:用于POST请求体。
    @POST("API/public")
    Call postBody(@Body ResponseBody body);
  • 允许图片和文字添加到请求体中上传

          RequestBody requestBody = new MultipartBody.Builder()
                  .setType(MultipartBody.FORM)
                  .addFormDataPart("name", name)
                  .addFormDataPart("image", file.getName(), RequestBody.create(MediaType.parse("image/*"),file))
                  .build();
    
           Call call = APIService.postBody(requestBody);
           ...

缓存机制

  • 缓存的优点:

    • 减少访问服务器的次数,降低服务器的负荷
    • 当没有网络的时候,界面不会显示空白,提高用户体验
  • 缓存机制的原理:
    我们请求服务器,然后由服务器返回的响应(Response) 中添加的头信息中有 Cache-control 字段,它的目的是告诉客户端是要从本地读取缓存还是直接从服务器摘取消息。它有不同的值,每一个值有不同的作用。
    如果我们需要满足这样的一个需求:“没有网络时读取本地缓存,有网络时获取服务器最新数据”就得做出判断:

    • 没有网络时将Cache-control 的字段值替换为“” public, max-age=” + 60”,意思是无网络时,设置缓存时间为60秒,超过60秒后不再读取缓存,重新访问服务器。
    • 没有网络时将Cache-control 的字段值替换为“” public, max-age=” + 0”,意思是有网络时,设置缓存时间为0秒,总是访问服务器获取最新数据。
      因此,需要Interceptor(拦截器)得到Response,从而对头信息进行以上配置。
  • 自定义Interceptor
    Interceptor的概念不再赘述,请参考http://www.jianshu.com/p/2710ed1e6b48,直接上代码:

    Interceptor mInterceptor = new Interceptor() {
          @Override
          public Response intercept(Chain chain) throws IOException {
              Request request = chain.request();
              if (!isNetworkReachable()) {
                  request = request.newBuilder()
                           //当没有网络时
                           //CacheControl.FORCE_CACHE; //仅仅使用缓存
                           //CacheControl.FORCE_NETWORK;// 仅仅使用网络
                          .cacheControl(CacheControl.FORCE_CACHE)
                          .build();
                  Log.d("flag", "no network");
              }
    
              Response proceed = chain.proceed(request);
    
              if (isConnectingToInternet()) {
                  //有网
                  //String cacheControl = request.cacheControl().toString();
                  return proceed.newBuilder()
                           //清除头信息
                          .removeHeader("Pragma")
                           //设置缓存时间为0秒,表示总不缓存
                          .header("Cache-Control", "public, max-age=" + 0)
                          .build();
              } else {
                  //没网
                  int maxTime = 4 * 24 * 60 * 60;//缓存时间:4周
                  return proceed.newBuilder()
                          .removeHeader("Pragma")
                           //设置缓存时间为4周,
                          .header("Cache-Control", "public, only-if-cached, max-stale=" + maxTime)
                          .build();
              }
          }
      };
  • 缓存文件

          File file = new File(getCacheDir(), "whstywh");//缓存文件路径
          Cache cache = new Cache(file, 10 * 1024 * 1024);//缓存文件大小为10MB

    缓存文件全是以url的md5加密字段为文件名,每一个response分两个文件保存,以.0和.1结尾的文件区分。 进去看里面的内容如下:

    • .0的文件记录header的信息:
    • .1文件里面是返回的具体内容,即json数据。由此可见,这里的缓存机制也是一开始先把json缓存进文件,没有网络的时候再读取json进行解析。
    • journal.文件里面保存的是每一条reponse记录状态。包括读取,删除,写入等动作。
  • 实现

          OkHttpClient client = new OkHttpClient.Builder()
                  .addInterceptor(mInterceptor)//添加应用拦截器
                  .addNetworkInterceptor(mInterceptor)//添加网络拦截器
                  .cache(cache)//设置缓存
                  .connectTimeout(5, TimeUnit.SECONDS)//连接超时 5秒
                  .build();
    
          Retrofit retrofit = new Retrofit.Builder()
                  .client(client)
                  .baseUrl("http://www.yuyigufen.com/")
                  .addConverterFactory(GsonConverterFactory.create())
                  .build();
    
                  ...
小结
IT文库 » Retrofit 2.x
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址