Retrofit网络请求框架要点总结

Retrofit网络请求框架要点总结

概述

  1. Retrofit2是利用接口、方法和注解参数来声明定义请求的。

  2. 默认采用OkHttp(retrofit1.x中用的是Square包下的,retrofit2.0用的是okHttp3,两者api有较大不同)做请求代理,序列化没有默认需要自己定义。

  3. 可以同步发送请求,也可以异步发送请求 异步时候需要定义回调,同步时候需要处理异常。

  4. 缓存采用OkHttp自带缓存进行处理。

示例

网络权限

 

使用retrofit1.x时gradle依赖库

dependencies {
compile 'com.google.code.gson:gson:2.3'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2' 
compile 'com.squareup.okhttp:okhttp:2.4.0'

}

使用retrofit2.0时gradle依赖库

 compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
 compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3' 
 从retrofit2.0开始,在Retrofit包中将不包含Converter,所以需要手动的插入一个转换器在Retrofit中,否则只能接受String结果,所以Retrofit2.0不再依赖Gson。

以下是基于Retrofit2.0的讲解

定义数据模型

public class ArticlesModel {
    .....
}

定义接口

/**
 * 爱卡汽车app首页请求接口
 * http://a.xcar.com.cn/interface/6.0/newsList.php/*type=1&provinceId=xxx&cityId=xxx&offset=xxx&limit=xx*x&ver=xxx
 */
interface MainHttpServer{
    //设置头信息 保存缓存
    @Headers("Cache-Control: public, max-age=604800 ,max-stale=2419200")
    // maxAge max-stale感觉两个类类似 都是设置最大失效时间,失效则不使用 需要服务器配合
    //get请求
    @GET("newsList.php")
    Call requestArticles(
            @Query("type") String type,
            @Query("provinceId") String provinceId,
            @Query("cityId") String cityId,
            @Query("offset") String offset,
            @Query("limit") String limit,
            @Query("ver") String ver
    );
}

初始化Retrofit

//初始化Retrofit .baseUrl必须得有
    Retrofit.Builder build = new Retrofit.Builder()
            .baseUrl("http://a.xcar.com.cn/interface/6.0/")
            .addConverterFactory(GsonConverterFactory.create());

创建Retrofit

//通过.build创建Retrofit
    Retrofit retrofit = build.build();

获取接口数据拿到Call

//通过retrofit.create() 动态代理拿到接口
    MainHttpServer service = retrofit.create(MainHttpServer.class);
    //调用接口的方法 其实内部进行了url拼接 准备请求等操作 因为service实际是一个动态代理类
    Call call = service.requestArticles("1","","",String.valueOf(mOffset),String.valueOf(mOffset+LIMIT),"6.0");

创建回调请求链接

//创建请求回调
    Callback mainCallBack = new ArticlesCallBack(loadType);
    //异步执行请求 如需同步 调用execute()方法
    call.enqueue(mainCallBack);

回调的定义

private class ArticlesCallBack implements Callback {

    @Override
    public void onResponse(Call call, Response response) {
      //请求成功
      ..............
    }

    @Override
    public void onFailure(Call call, Throwable t) {
       //请求失败
       .............
    }
}

如果使用缓存

//初始化OkHttp所用的缓存 以及OKhttp请求
    File cacheFile = new File(mContext.getCacheDir(), "xcar-cache");
    Cache cache = new Cache(cacheFile,10 * 1024 * 1024);
    OkHttpClient client = new OkHttpClient.Builder()
            .cache(cache)
            .build();
    //在初始化Retrofit的时候 将OkHttpClient设置进去
    Retrofit.Builder build = new Retrofit.Builder().client(client);
//使用缓存需要在接口方法里面声明(见接口定义)
//@Headers("Cache-Control: public, max-age=604800 ,max-stale=2419200")

Retrofit中URL的处理

 Retrofit.Builder build = new Retrofit.Builder()
        .baseUrl("http://a.xcar.com.cn/interface/6.0/")
        .addConverterFactory(GsonConverterFactory.create());
上边的baseUrl为http://a.xcar.com.cn/interface/6.0/

1.@GET("newsList.php")
Call requestArticles(
        @Query("type") String type,
        @Query("provinceId") String provinceId,
        @Query("cityId") String cityId,
        @Query("offset") String offset,
        @Query("limit") String limit,
        @Query("ver") String ver
);
这种形式的请求组成的url为:
http://a.xcar.com.cn/interface/6.0/newsList.php/type=1&provinceId=xxx&cityId=xxx&offset=xxx&limit=xxx&ver=xxx

2.@GET("/newsList.php")
Call requestArticles();
这种形式的请求组成的url为:
http://a.xcar.com.cn/newsList.php

3.@GET("newsList.php/{id}/user")
Call requestArticles(@path("id") int id);

假设传入的id为111,最后生成的地址为:
http://a.xcar.com.cn/interface/6.0/newsList.php/111/user

总结

Retrofit的使用就是以下几步:

  1. 定义接口,参数声明,Url都通过Annotation指定 Annotation写在接口内方法上
  2. 通过Retrofit生成一个接口的实现类(动态代理)
  3. 调用接口请求数据
  4. Base URL:永远用 / 结尾

进阶

Converter数据转换器

Retrofit2中可以使用的Converter有以下几种

  1. Gson com.squareup.retrofit2:converter-gson:2.0.0-beta3
  2. Jackson com.squareup.retrofit2:converter-jackson:2.0.0-beta3
  3. Moshi com.squareup.retrofit2:converter-moshi:2.0.0-beta3
  4. Protobuf com.squareup.retrofit2converter-protobuf:2.0.0-beta3
  5. Wire com.squareup.retrofit2:converter-wire:2.0.0-beta3
  6. Simple XML com.squareup.retrofit2converter-simplexml:2.0.0-beta3

    //添加一个GSON的转换器
    Retrofit.Builder build = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create());
    

Converter可以添加一个也可以添加多个如下所示,额外添加一个Proto的Converter,一个错误的例子如下

Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ProtoConverterFactory.create())
.build();

!!注意上述写法是错误的!!  

添加 converter 的顺序很重要 GSON必须放在最后,下面是正确的

Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(ProtoConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();

参数注解

public interface MyApiEndpointInterface {
// Request method and URL specified in the annotation
// Callback for the parsed response is the last parameter
@Headers("Cache-Control: public, max-age=604800 ,max-stale=2419200")
@GET("/users/{username}")
Call getUser(@Path("username") String username);
@GET("/group/{id}/users")
Call> groupList(@Path("id") int groupId, @Query("sort") String sort);
@POST("/users/new")
Call createUser(@Body User user);
}

上面的例子中可以看到:

定义在方法上的注解:
  • @GET 发起GET请求
  • @POST 发起POST请求
定义在参数上的注解:
  • @Path 用于替代路径中定义的{xxx}里面的值,
  • @Query 就是在GET请求中指定的键值对请求 例如@Query(“sort”) String sort就是对应在Url中添加sort=(String sort)
  • @Body 用于POST请求的请求体 可以直接传递一个对象
其他注解
  1. 表单提交多参数的数据 @Multipart + @Part

    @Multipart
    @POST("/some/endpoint")
    Call someEndpoint(@Part("name1") String name1, @Part("name2") String name2)
    
  2. 表单提交多参数数据 @FormUrlEncoded + @Field

    @FormUrlEncoded
    @POST("/user/edit")
    User updateUser(@Field("first_name") String first, @Field("last_name") String last);
    
  3. 表单提交一个Map的键值对 @FormUrlEncoded + @FieldMap

    @FormUrlEncoded
    @POST("/some/endpoint")
    Call someEndpoint(@FieldMap Map names);
    
  4. Header注解 @Headers

    • 静态注解
      对个header
      interface FixedHeader{
      @Headers({ //静态Header
      “Accept: application/vnd.github.v3.full+json”,
      “User-Agent: Retrofit-Sample-App”
      })
      @GET(“/”)
      Response getResponse();
      }

    • 动态注解
      单一header
      interface DynamicHeader{
      @Headers(“Cache-Control: max-age=640000”) //静态Header
      @GET(“/”)
      Response getResponse(@Header(“header1”)String header1,@Header(“header2”)String header2); //动态Header,其value值可以在调用这个方法时动态传入.
      }

注意事项

  • 一般地,base URL是在实例化 Retrofit instance 的时候定义的。Retrofit 2 允许你在注解里面重写base URL 。

    @POST("https://api.github.com/api/v3")
    
  • call.execute()同步方法只能执行一次。第二次会出异常 想要再用 .clone()

    Call> call =
      gitHubService.repoContributors("square", "retrofit");
    response = call.execute();
    // This will throw IllegalStateException:
    response = call.execute();
    Call> call2 = call.clone();
    // This will not throw:
    response = call2.execute();
    
  • 可以调用cancel()来立刻取消请求

    Call> call =
      gitHubService.repoContributors("square", "retrofit");
    call.enqueue(        );
    // or...
    call.execute();
    // later...
    call.cancel();
    
  • 在CallBack回调里面有Response类,在该类中可以得到响应码,响应信息,响应头(code message handers)

    注意:如果返回码是200 但是最终返回false的情况 实际是无法判断返回到底是什么 自己处理budy即可

  • 注意必须声明Converters,现在没有默认的Converter

  • 经过测试: baseUrl必须设置,如果 声明接口时@GET使用了完整的url路径,那么baseUrl就会被忽略,否则就是拼接url

对Retrofit框架的理解

Retrofit使用了三行代码就完成了创建链接+请求

// 创建一个GitHub接口的请求
XcarInter xcar = retrofit.create(XcarInter.class);
//创建Call的实例 准备请求
Call call = xcar.requestData("xxx", "xxx");
//执行请求
call.enqueue(new MyCallBack(){
     @Override
    public void onResponse(Call call, Response response) {
     ...
    }

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

在retrofit.create()的时候,create()方法内部执行动态代理得到接口对象,这时候xcar这个接口对象并不是implements对象,当xcar调用了接口对应的方法后执行的其实是动态代理的方法,看上去调用接口方法,实际Retrofit将Xcar接口翻译成为一个HTTP请求,也就是源码中的MethodHalder对象。实际是MethodHalder对象来处理后续的请求操作。

你可能感兴趣的:(Android技术整)