使用Retrofit处理复杂接口地址类型
使用Retrofit处理复杂接口地址类型
1. @Path注解和@query注解
2. ResponseBody是啥
interface ExampleService {
@DELETE("data/{id}")
fun deleteData(@Path("id") id: String): Call<ResponseBody>
}
在返回值声明的时候,我们将Call的泛型指定成了ResponseBody,这是什么意思呢?
由于POST、PUT、PATCH、DELETE这几种请求类型与GET请求不同,它们更多是用于操作服务器上的数据,而不是获取服务器上的数据,所以通常它们对于服务器响应的数据并不关心。这个时候就可以使用ResponseBody,表示Retrofit能够接受任意类型的响应数据,并且不会对响应数据进行解析。
3. @Body注解 P458
向服务器提交数据,使用POST请求,需要将数据放到HTTP请求的body部分,这个功能在Retrofit中可以借助@Body注解来完成:
interface ExampleService {
@POST("data/create")
fun createData(@Body data: Data): Call<ResponseBody>
}
当Retrofit发出POST请求时,就会自动将Data对象中的数据转换成JSON格式的文本,并放到HTTP请求的body部分,服务器在收到请求之后只需要从body中将这部分数据解析出来即可。
4. @Headers注解和@Header注解
有些服务器接口还可能会要求我们在HTTP请求的header中指定参数。这些header参数其实就是一个个的键值对,我们可以在Retrofit中直接使用@Headers注解来对它们进行声明。
interface ExampleService {
@Headers("User-Agent: okhttp", "Cache-Control: max-age=0")
@GET("get_data.json")
fun getData(): Call<Data>
}
但是这种写法只能进行静态header声明,如果想要动态指定header的值,则需要使用@Header注解:
1 interface ExampleService {
2 @GET("get_data.json")
3 fun getData(@Header("User-Agent") userAgent: String, @Header("Cache-Control") cacheControl: String): Call<Data>
4 }
5. Service接口的动态代理对象是什么 P459
不熟悉动态代理也没关系,只需要知道有了动态代理对象之后,就可以随意调用接口中定义的所有方法,而Retrofit会自动执行具体的处理就可以了。
6. Retrofit构建器的最佳写法
object ServiceCreator {
private const val BASE_URL = "http://10.0.2.2/"
private val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
fun <T> create(serviceClass: Class<T>): T = retrofit.create(serviceClass)
// 或者更加简洁,不带参数的create()方法
// inline fun <reified T> create(): T = create(T::class.java)
}