展开说说Android之Retrofit详解_使用篇

Retrofit是由Square公司开发的类型安全HTTP客户端框架,借助动态代理运行时生成接口实现类将注解转化为OkHttp请求配置节省成本通过转换器(Gson/Moshi)自动序列化JSON/XML内部处理网络请求在主线程返回报文。Retrofit 直译是封装、翻版。他就是对okhttp做了进一步封装,方便使用,它底层的所有请求默认走的都是Okhttp。  所以使用Retrofit必须依赖okHttp。

两者区别:Retrofit是基于App发请求的封装,也就是面向的应用层(比如响应数据的处理和错误处理等),而Okhhtp是对底层网络请求的封装与优化(socket优化,数据压缩,buffer缓存等)

本文将通过GET/POSTde 基础请求、文件上传、动态URL、缓存转换器,以及借助OKHttp实现Retrofit请求过程中设置请求头、cookie、超时时间和拦截器都是借助OkHttpClient 等。

1、添加依赖:

使用Retrofit添加的依赖,另外,使用转换器也需要在build.gradle中单独引入,两种转换器通常不同时使用,根据项目JSON处理需求选择其一即可

dependencies {
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
}

GsonConverterFactory依赖配置

implementation 'com.squareup.retrofit2:converter-gson:2.9.0' 
implementation 'com.google.code.gson:gson:2.8.8' 

MoshiConverterFactory依赖配置: 

    implementation 'com.squareup.retrofit2:converter-moshi:2.9.0' 
    implementation 'com.squareup.moshi:moshi:1.14.0' // Moshi

      2、业务场景实现

      先定义一个接口:

      切记这里必须是interface!!!

      public interface RequestService {
          @GET("login/{id}")
          Call login(@Path("id") int userId);
      
          @POST("users/new")
          @Headers("Content-Type: application/json") // 设置请求头
          Call loginPost(@Body LoginInfo loginInfo); // @Body注解表示请求体
      
          @Multipart // 表示多部分请求
          @POST("upload")
          Call uploadFile( @Part("description") RequestBody description,  @Part MultipartBody.Part file);
      
          // 借助@Url注解,指定完整URL
          @GET
          Call getCustomUrl(@Url String url);
      
          //借助Query注解,添加查询参数
          @GET("search")
          Call queryData(@Query("q") String query);
      
      }

      定义实体类 LoginInfo.java

      public class LoginInfo {
          private String userNmae;
          private String userPwd;
      
          public LoginInfo(String userNmae, String userPwd) {
              this.userNmae = userNmae;
              this.userPwd = userPwd;
          }
      }

      定义初始化Retrofit的单例工具类 RetrofitUtil.java

      public class RetrofitUtil {
          private static RetrofitUtil retrofitUtil;
          private Retrofit retrofit;
          File httpCacheDirectory = new File(BaseApplication.getContext().getCacheDir(), "responses");
          int cacheSize = 10 * 1024 * 1024; // 10MB
          Cache cache = new Cache(httpCacheDirectory, cacheSize);
      
          private RetrofitUtil(){
      
          }
      
          public static RetrofitUtil getInstance(){
              synchronized (RetrofitUtil.class){
                  if (retrofitUtil == null){
                      retrofitUtil = new RetrofitUtil();
                  }
                  return retrofitUtil;
              }
          }
      
          public  T getServer(Class cls, String baseUrl){
              if (retrofit == null){
                  retrofit = new Retrofit.Builder()
                          .baseUrl(baseUrl)
                          .client(getClient())
                          .addConverterFactory(GsonConverterFactory.create())
                          .build();
              }
              return retrofit.create(cls);
          }
      
          public OkHttpClient getClient(){
              // 创建OkHttpClient
              OkHttpClient okHttpClient = new OkHttpClient.Builder()
      //                .cookieJar()
                      .connectTimeout(10, TimeUnit.SECONDS)
                      .readTimeout(10, TimeUnit.SECONDS)
                      .writeTimeout(10, TimeUnit.SECONDS)
                      .addInterceptor(new Interceptor() {
                          @Override
                          public Response intercept(Chain chain) throws IOException {
                              Request request = chain.request();
                              // 添加统一请求头
                              request = request.newBuilder()
                                      .header("Cache-Control", "public, max-age=60")
                                      .build();
                              return chain.proceed(request);
                          }
                      })
                      .cache(cache)
                      .build();
              return okHttpClient;
          }
      }

      注意Retrofit在设置请求头、cookie、超时时间和拦截器都是借助OkHttpClient 来实现。

      2.1 Get请求

      getTv.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              int id = 600001;
              RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).login(id).enqueue(new Callback() {
                  @Override
                  public void onResponse(Call call, Response response) {
                      if (response.isSuccessful()) {
                          LoginInfo loginInfo = response.body(); // 自动解析JSON为User对象
                      }
                  }
                  @Override
                  public void onFailure(Call call, Throwable t) {
                      t.printStackTrace();
                  }
              });
      
          }
      });

      2.2 POST请求

      LoginInfo loginInfo = new LoginInfo("Admin", "12345678");
      // 发起请求
      Call call = RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).loginPost(loginInfo);
      call.enqueue(new Callback() {
          @Override
          public void onResponse(Call call, Response response) {
              // 请求成功
          }
      
          @Override
          public void onFailure(Call call, Throwable t) {
              // 请求失败
          }
      });

      2.3 文件上传

      // 准备文件
      File file = new File("path/to/file.jpg");
      RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), file);
      MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
      
      // 发起上传请求
      RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).uploadFile(
              RequestBody.create(MediaType.parse("text/plain"), "文件描述"),
              body).enqueue(new Callback() {
          @Override
          public void onResponse(Call call, Response response) {
              //处理上传成功后的逻辑
          }
      
          @Override
          public void onFailure(Call call, Throwable t) {
              //处理上传失败的逻辑
          }
      });

      2.4动态指定URL和添加查询参数

      一般来说一个项目中你可能定封装了公共个请求路径和域名,但有个别接口就需要特立独行的地址和传参,此时可以借助@Url和@Query动态的实现。 两个请求也在上面给出的RequestService 这个接口中定义了。

              // 使用动态URL
              Call call1 = RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).getCustomUrl("https://api.example.com/custom/path");
      
              // 使用查询参数
              Call call2 = RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).queryData("retrofit");

      个人总结记录,才疏学浅,如有错误,欢迎指正,多谢。 

      你可能感兴趣的:(网络编程,android,retrofit,网络)