Retrofit2 笔记

Retrofit 基础

  • 在 Retrofit 中使用注解的方式来区分请求类型

    格式含义
    @GET表示这是一个 GET 请求
    @POST表示这是一个 POST 请求
    @PUT表示这是一个 PUT 请求
    @DELETE表示这是一个 DELETE 请求
    @HEAD表示这是一个 HEAD 请求
    @OPTIONS表示这是一个 OPTIONS 请求
    @PATCH表示这是一个 PATCH 请求
  • 在 Retrofit 中的参数(@Path、@Query、@QueryMap、@Body、@Field)

    • 初始化 Retrofit

      String BASE_URL = "http://102.10.10.132/api/";
      Retrofit retrofit = new Retrofit.Builder()
              .baseUrl(BASE_URL)
              .build();
      
    • GET 请求

      链接方式
      http://102.10.10.132/api/News@GET(“News”)Call getItem();
      /api/News/{资讯id}@GET(“News/{newsId}”)Call getItem(@Path(“newsId”) String newsId);
      /api/News/{资讯id}/{类型}@GET(“News/{newsId}/{type}”)Call getItem(@Path(“newsId”) String newsId, @Path(“type”) String type);
      /api/News?newsId={资讯id}@GET(“News”)Call getItem(@Query(“newsId”) String newsId);
      /api/News?newsId={资讯id}&type={类型}@GET(“News”)Call getItem(@Query(“newsId”) String newsId, @Query(“type”) String type);
      /api/News?newsId={资讯id}&type={类型}…@GET(“News”)Call getItem(@QueryMap Map< String,String> map); 或者 @GET(“News”)Call getItem(@Query(“newsId”) String newsId,@QueryMap Map< String,String> map);
    • POST 请求

      链接方式
      http://102.10.10.132/api/Comments/{newsId}@FormUrlEncoded@POST(“Comments/{newsId}”)CallreportComment(@Path(“newsId”) String commentId,@Field(“reason”) String reason);
      /api/Comments/{newsId}?access_token={access_token}@FormUrlEncoded@POST(“Comments/{newsId}”) Call reportComment(@Path(“newsId”) String commentId,@Query(“access_token”) String access_token,@Field(“reason”) String reason);
      /api/Comments/{newsId}?access_token={access_token}@POST(“Comments/{newsId}”)Call reportComment( @Path(“newsId”) String commentId,@Query(“access_token”) String access_token,@Body CommentBean bean);
    • DELETE 请求

      链接方式
      http://102.10.10.132/api/Comments/{newsId}@DELETE(“Comments/{commentId}”)Call deleteNewsCommentFromAccount(@Path(“commentId”) String commentId);
      /api/Comments/{newsId}?access_token={access_token}@DELETE(“Comments/{commentId}”)Call deleteNewsCommentFromAccount(@Path(“accountId”) String accountId,@Query(“access_token”) String access_token);
    • PUT 请求

      链接方式
      http://102.10.10.132/api/Accounts/{accountId}@PUT(“Accounts/{accountId}”)Call updateExtras(@Path(“accountId”) String accountId,@Query(“access_token”) String access_token,@Body ExtrasBean bean);
    • 总结

    • 注意!!!!!!!!!

      • 使用@Field时记得添加@FormUrlEncoded
      • 若需要重新定义接口地址,可以使用@Url,将地址以参数的形式传入即可,如:

        @GETCall

Retrofit 进阶

  • Call 引入

    • Retrofit 2 里引入了 call 方法。语法和 OkHttp 基本一模一样,唯一不同是这个函数知道如何做数据的反序列化。它知道如何将 HTTP 响应转换成对象。

      interface GitHubService {
        @GET("/repos/{owner}/{repo}/contributors")
        Call<List<Contributor>> repoContributors(@Path("owner") String owner,@Path("repo") String repo);
      }
      
      Call<List<Contributor>> call =gitHubService.repoContributors("square", "retrofit");
      
    • 每个 Call 实例只能被使用一次,若想再次使用,可以通过 clone 一个之前的实例

      Call<List<Contributor>> call = gitHubService.repoContributors("square", "retrofit");
      
      response = call.execute();
      
      //再次使用,会报 非法异常
      response = call.execute();
      
      Call<List<Contributor>> call2 = call.clone();
      // This will not throw:
      response = call2.execute()
      
    • Retrofit 2 支持在同一个类型中进行同步和异步请求

      Call<List<Contributor>> call = gitHubService.repoContributors("square", "retrofit");
      
      call.enqueue(new Callback<List<Contributor>>() {
        @Override void onResponse(/* ... */) {
          // ...
        }
      
        @Override void onFailure(Throwable t) {
          // ...
        }
      });
      
    • 可以随时调用 cancel 方法来取消请求

      Call<List<Contributor>> call = gitHubService.repoContributors("square", "retrofit");
      
      call.enqueue(         );
      // or...
      call.execute();
      
      // later...
      call.cancel();
      
  • 参数化的 Response 对象; Response 对象增加了曾经一直被我们忽略掉的重要元数据:响应码(the reponse code),响应消息(the response message),以及读取相应头(headers)。

    class Response<T> {
      int code();
      String message();
      Headers headers();
    
      boolean isSuccess();
      T body();
      ResponseBody errorBody();
      com.squareup.okhttp.Response raw();
    }
    
  • 动态 URL 参数

    interface GitHubService {
      @GET("/repos/{owner}/{repo}/contributors")
      Call<List<Contributor>> repoContributors(
          @Path("owner") String owner,
          @Path("repo") String repo);
    }
    
    Call<List<Contributor>> call =
        gitHubService.repoContributors("square", "retrofit");
    Response<List<Contributor>> response = call.execute();
    
    • Retrofit 2.0 有了新的 标注:@Url ,允许你直接传入一个请求的 URL。

      @GET
      Call<List<Contributor>> repoContributorsPaginate(@Url String url);
      
  • 更多更有效的转换器(Converters)

    • 每一个 converter 会被询问是否能够处理某种类型,如果可以,就会被处理,否则,询问下一个类型的 converter。如 proto convertor、JSON converter 等;注意:JSON 没有什么继承上的约束,所以我们无法通过什么确切的条件来判断一个对象是否是 JSON 对象,故 JSON 的 converters 会对任何的数据都认为是可以处理的,所以,一定要将 JSON converter 放在最后进行判断。
    • Retrofit 2 已经不提供默认的 converter了。如果不显性的声明一个可用的 Converter 的话,Retrofit 是会报错的:提醒你没有可用的 Converter。因为核心代码已经不依赖序列化相关的第三方库了,我们依然提供对 Converter 的支持,不过你需要自己引入这些依赖,同时显性的声明 Retrofit 需要用的 Converter 有哪些。
  • 更多可替换的执行机制

    • 在此之前,Retrofit 有一个死板的 execution 流程。在 Retrofit 2 里,我们调整了整个流程,让它变得可替换(pluggable),同时允许多个。跟 converter 的工作原理很像。比如说,你有一个方法返回了一个 Call 对象,Call 是内置的 Converter 类型。比如:Retrofit 2 的执行机制:

      interface GitHubService {
        @GET("/repos/{owner}/{repo}/contributors")
        Call<List<Contributor>> repoContributors(
            @Path("owner") String owner,
            @Path("repo") String repo);
            ...
      现在我们可以自己定义这些了:
      ...
      
        @GET("/repos/{owner}/{repo}/contributors")
        Observable<List<Contributor>> repoContributors2(
            @Path("owner") String owner,
            @Path("repo") String repo);
      
        @GET("/repos/{owner}/{repo}/contributors")
        Future<List<Contributor>> repoContributors3(
            @Path("owner") String owner,
            @Path("repo") String repo);
      }
      

Retrofit 2 常见使用场景

  • Retrofit 2 现在依赖 OkHttp,并没有 Http Client 层的抽象。但是现在我们可以传递一个配置好的 OkHttp 实例的,如修改 OkHttp 默认的超时时长

    OkHttpClient client=new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(20,TimeUnit.SECONDS)
            .build();
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("")
            .client(client)
            .build();
    
  • 如果要添加 converter 机制,也是如添加 Client 一样的:

    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com")
        .addConverterFactory(ProtoConverterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build();
    
  • 如果要添加 execute 机制,即使用 RxJava 来代替 call,也是如添加 Client 一样的:

    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com")
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build();
    
  • 扩展性,如 Factory 的扩展,即写属于自己的 Call Adapter Facotory

测试 Demo

ILoginService service = RetrofitInstance.getInstance().create(ILoginService.class);
Call<ResponseBody> call = service.geUserInfo("RlWW73");
/*//同步调用
Response<ResponseBody> bodyResponse = null;
try {
    bodyResponse = call.execute();
    String body = bodyResponse.body().string();//获取返回体的字符串
    Log.e(TAG, "onClick: "+body);
} catch (IOException e) {
    e.printStackTrace();
}*/
//异步调用
call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        try {
            String resultBody = new String(response.body().bytes());
            Log.e(TAG, "onResponse: " + resultBody);
            //第一种方式:通过 Gson 解析
            JsonParser parser = new JsonParser();
            JsonElement element = parser.parse(resultBody);
            JsonObject object = element.getAsJsonObject();
            object.get("Code").getAsInt();
            Buyer buyer = new Gson().fromJson(object.get("Data"), Buyer.class);
            Log.e(TAG, "onResponse: " + object.get("Code").getAsInt() + buyer.toString());
            //第二种方式:通过 json 解析
            JSONObject jsonObject = new JSONObject(resultBody);
            int code = jsonObject.optInt("Code");
            Buyer buyer1=new Gson().fromJson(object.get("Data").toString(), Buyer.class);
            Log.e(TAG, "onResponse: " + jsonObject.optInt("Code")+"-->"+buyer1.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        t.printStackTrace();
    }
});

参考引用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值