Retrofit 2.x 系列之一 - Retrofit的使用姿势(基础篇)

文章使用的Retrofit版本为:2.3.0

Retrofit已经问世很久了,现在再来讨论Retrofit的使用不免有些晚,但是也是为了巩固自己的知识,话不多说,直接开始:

Retrofit是什么?

其实Retrofit是对网络请求的一种封装,实际进行网络请求的并不是它本身,Retrofit内部依赖了okhttp与okio,就像我们在使用okhttp时进行封装一样,Retrofit通过一系列初始化配置之后,让我们可以通过注解的方式就能进行网络请求,很大程度上简化了我们在实际请求时所需要做的操作。
Retrofit内部依赖

Retrofit怎么用?
  1. 添加依赖:
implementation 'com.squareup.retrofit2:retrofit:2.3.0'

因为Retrofit已经内部依赖了okhttp,所以我们不需要额外再去添加依赖了。

  1. Retrofit初始化配置
object RetrofitCreate {
    fun getApi(): Api {
        return Retrofit.Builder()
                .baseUrl("http://www.baidu.com/")
                .client(OkHttpClient())
                .build()
                .create(Api::class.java)
    }
}

我们从以上的几个方法开始看:
1、baseUrl()必需项,设置的是接口请求中的url基地址,必须以 / 结尾,否则会报错(原因我们在往后源码解析的文章中能知道),并且在调用A接口时如果注解中的地址已经包含了基地址,那么A接口每次调用时都以它自己的基地址覆盖设置的baseUrl,其他接口还是使用baseUrl。
2、client()可选项,设置的是OkhttpClient ,我们可以对OkHttpClient进行自定义,如果不配置的话Retrofit会使用默认的OkhttpClient。
3、cteate()必需项,指定我们将Retrofit的初始化与哪一个配置接口相结合。

  1. 添加请求配置的接口

这里以 GET 请求举例

interface Api {
    @GET("hello/world")
    fun getHelloWorld(@Query("name") name: String): Call<String>
}

@GET("hello/world") 这个方法上的注解就定义了这个接口的请求方式为 GET、url为 hello/world ,这里的url会和第二步中Retrofit中的初始化配置协同工作,并且,如果你这里写的是完整路径,那么在Retrofit初始化时设置的baseUrl将在此次接口调用中无效,注意是 此次,并不会就此覆盖baseUrl。

@Query 这个参数的注解含义为参数名为字符串 name ,参数的值为调用时传入的值,方法的注解和参数的注解是搭配来使用的,这个我们稍后介绍。

Call<String> 为返回值,返回类型为 String,call 为Retrofit的包装类,能够调用同步、异步方法发起请求,实际发起请求的操作是转交到了Okhttp和okio去做。

发起异步的 GET 请求:

RetrofitCreate.getApi().getHelloWorld("jerry").enqueue(object:Callback<String>{
        override fun onFailure(p0: Call<String>?, p1: Throwable?) {
        }

        override fun onResponse(p0: Call<String>?, p1: Response<String>?) {
        }
    })

结合图示代码的完整请求信息如下:
请求接口:http://www.baidu.com/hello/world?name=jerry
请求方法:GET
因为是 get 请求,参数已经拼接到了 url 上。

至此,一个简单的请求我们就完成了。当然,Retrofit 可不仅仅只有这点内容,Retrofit 的使用就是对其内部定义的各种注解的使用,所以我们就从注解开始。

Retrofit的注解

Retrofit的注解类型
这就是所谓的开局一张图,剩下全靠吹:

  1. 方法注解
注解作用
@GET表明HTTP请求方法为GET,(可选)注解的value属性用来设置相对/绝对url
@POST表明HTTP请求方法为POST,(可选)注解的value属性用来设置相对/绝对url
@PUT表明HTTP请求方法为PUT,(可选)注解的value属性用来设置相对/绝对url
@DELETE表明HTTP请求方法为DELETE ,(可选)注解的value属性用来设置相对/绝对url
@HEAD表明HTTP请求方法为HEAD,(可选)注解的value属性用来设置相对/绝对url
@PATCH表明HTTP请求方法为PATCH,(可选)注解的value属性用来设置相对/绝对url
@OPTIONS表明HTTP请求方法为OPTIONS,(可选)注解的value属性用来设置相对/绝对url
@HTTP通过@HTTP注解指定http协议的请求方法,是否允许body,(可选)注解的value属性用来设置相对/绝对url
@Headers使用注解的value值数组作为HTTP的请求头,用于一些固定的Header参数

1.1. 标记类注解

注解作用
@FormUrlEncoded表明发起HTTP请求的RequestBody是form表单方式
@Multipart表明发起HTTP请求的RequestBody是Multipar方式
@Streaming用于直接返回流的函数
  1. 参数注解
注解作用
@UrlHTTP请求的url路径(相对/绝对),可以包含{path},如:http://xxx.com/{path1}/detail
@Body表明此参数用作HTTP请求的body
@Path用于动态替换URL路径中的 {path}
@Field表明此参数用作HTTP请求的form表单参数,表单参数的key为注解的value值
@FieldMap以map形式传入的form表单参数
@Part表明参数为Http的multipart参数之一
@PartMap以map形式传入的multipart参数表
@QueryGET方法的query参数,用于拼接完整请求路径
@QueryMap以map传入的GET方法的query参数,用于拼接完整请求路径
@Header表明此参数用作HTTP请求的header,请求头的key为注解的value值
@HeaderMap以map形式传入的多个header键值对

直接用代码展示各个注解的使用方式:

interface Api {

    //使用@Headers添加多个请求头
    @Headers("User-Agent:android", "apikey:123456789")
    @POST
    fun post(@Url url: String, @QueryMap map: Map<String, String>): Call<Any>

    @GET("hello/world")
    operator fun get(@Header("token") token: String, @Query("id") activeId: Int): Call<Any>

    @GET("hello/world")
    fun ActiveList(): Call<Any>

    @POST("hello/world")
    fun post2(@QueryMap map: Map<String, String>): Call<Any>

    /**
     * 很多情况下,我们需要上传json格式的数据。比如当我们注册新用户的时候,因为用户注册时的数据相对较多,
     * 并可能以后会变化,这时候,服务端可能要求我们上传json格式的数据。此时就要@Body注解来实现。
     * 直接传入实体,它会自行转化成Json
     */
    @POST("hello/{url}/world")
    fun login(@Path("url") url: String, @Body post: Any): Call<Any>

    /**
     * 单张图片上传
     * retrofit 2.0的上传和以前略有不同,需要借助@Multipart注解、@Part和MultipartBody实现。
     */
    @Multipart
    @POST("{url}")
    fun upload(@Path("url") url: String, @Part file: MultipartBody.Part): Call<Any>

    /**
     * 多张图片上传
     */
    @Multipart
    @POST("hello/world")
    fun upload(@PartMap map: Map<String, MultipartBody.Part>): Call<Any>

    /**
     * 图文混传
     */
    @Multipart
    @POST()
    fun register(@Body post: Any, @PartMap map: Map<String, MultipartBody.Part>): Call<Any>

    /**
     * 文件下载
     */
    @Streaming
    @GET
    fun downloadPicture(@Url fileUrl: String): Call<Any>

    /**
     * 这里需要注意的是如果下载的文件较大,比如在10m以上,那么强烈建议你使用@Streaming进行注解,否则将会出现IO异常.
     */
    @Streaming
    @GET
    fun downloadPicture2(@Url fileUrl: String): Call<Any>

    @POST
    @FormUrlEncoded
    fun executePost(@FieldMap maps: Map<String, Any>): Call<Any>
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值