配置
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl("http://baidu.com")
.client(getOkHttpClient())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.callbackExecutor(Executors.newSingleThreadExecutor())//call里回调的线程池,不设置默认回调安卓主线程
//在Retrofit实例上调用create时,是否立即生成接口中所有方法的动态代理实现缓存。false用到时生成,true会马上生成
//最好还是设置成false,一次性生成耗时
.validateEagerly(true)
.build()
协程
retrofit2.6.0版本前
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
.addCallAdapterFactory(CoroutineCallAdapterFactory.invoke())
@POST("/user/login")
fun login(@Field("username") userName: String,
@Field("password") passWord: String): Deferred<WanResponse<User>>
suspend fun login(userName: String, passWord: String): WanResponse<User> {
return apiCall { WanRetrofitClient.service.login(userName, passWord).await() }
}
fun login(userName: String, passWord: String) {
launch {
val response = withContext(Dispatchers.IO) { repository.login(userName, passWord) }
executeResponse(response, { mLoginUser.value = response.data }, { errMsg.value = response.errorMsg })
}
}
2.6.0后
//看到区别了吗?首先,不再返回 Deferred<T> 对象,而是直接返回我们需要的 WanResponse 对象。
//其次,使用了 suspend 来修改方法,标记这是挂起函数。
@POST("/user/login")
suspend fun login(@Field("username") userName: String,
@Field("password") passWord: String): WanResponse<User>
//与之前的版本相比,这里不需要调用 await 方法了。其实并不是不调用了,而是 Retrofit 帮助我们自动调用了。
suspend fun login(userName: String, passWord: String): WanResponse<User> {
return apiCall { WanRetrofitClient.service.login(userName, passWord) }
}
去除之前添加的 kotlin-coroutines-adapter,因为我们不再需要人工返回 Deferred<T> 对象,
也不再需要手动调用 await 了。
//.addCallAdapterFactory(CoroutineCallAdapterFactory.invoke())
注解
表单
FormUrlEncoded - 表单格式
Field - 配合@FormUrlEncoded使用,必须是表单请求
@FormUrlEncoded
@POST("/")
Call<ResponseBody> example(
@Field("name") String name,
@Field("occupation") String occupation);
Calling with foo.example("Bob Smith", "President") yields a request body of name=Bob+Smith&occupation=President.
Array/Varargs Example:
@FormUrlEncoded
@POST("/list")
Call<ResponseBody> example(@Field("name") String... names);
Calling with foo.example("Bob Smith", "Jane Doe") yields a request body of name=Bob+Smith&name=Jane+Doe.
FieldMap
Simple Example:
@FormUrlEncoded
@POST("/things")
Call<ResponseBody> things(@FieldMap Map<String, String> fields);
Calling with foo.things(ImmutableMap.of("foo", "bar", "kit", "kat") yields a request body of foo=bar&kit=kat.
请求头
Header
@GET("/")
Call<ResponseBody> foo(@Header("Accept-Language") String lang);
HeaderMap
@GET("/search")
void list(@HeaderMap Map<String, String> headers);
Headers
@Headers("Cache-Control: max-age=640000")
@GET("/")
...
@Headers({
"X-Foo: Bar",
"X-Ping: Pong"
})
@GET("/")
multi-part请求
Multipart and Part
@Multipart
@POST("/")
Call<ResponseBody> example(
@Part("description") String description,
@Part(value = "image", encoding = "8-bit") RequestBody image);
PartMap
@Multipart
@POST("/upload")
Call<ResponseBody> upload(
@Part("file") RequestBody file,
@PartMap Map<String, RequestBody> params);
其他
Body
对象将使用Retrofit实例转换器进行序列化,结果将直接设置为请求体。
@POST("adv-filter/AdInfoFilter/batchGetAdInfoList")
ICommonCall<BatchGetAdInfoRsp> getAdInfos(@Body AdInfoFilterReq reqBody);
Path
Values are URL encoded by default. Disable with encoded=true.
@GET("/user/{name}")
Call<ResponseBody> encoded(@Path("name") String name);
@GET("/user/{name}")
Call<ResponseBody> notEncoded(@Path(value="name", encoded=true) String name);
Calling foo.encoded("John+Doe") yields /user/John%2BDoe whereas foo.notEncoded("John+Doe") yields /user/John+Doe
Query
Simple Example:
@GET("/friends")
Call<ResponseBody> friends(@Query("page") int page);
Calling with foo.friends(1) yields /friends?page=1.
Example with null:
@GET("/friends")
Call<ResponseBody> friends(@Query("group") String group);
Calling with foo.friends(null) yields /friends.
Calling with foo.friends(null) yields /friends.
Array/Varargs Example:
@GET("/friends")
Call<ResponseBody> friends(@Query("group") String... groups);
Calling with foo.friends("coworker", "bowling") yields /friends?group=coworker&group=bowling.
Parameter names and values are URL encoded by default. Specify encoded=true to change this behavior.
@GET("/friends")
Call<ResponseBody> friends(@Query(value="group", encoded=true) String group);
Calling with foo.friends("foo+bar")) yields /friends?group=foo+bar.
QueryMap
Simple Example:
@GET("/friends")
Call<ResponseBody> friends(@QueryMap Map<String, String> filters);
Calling with foo.friends(ImmutableMap.of("group", "coworker", "age", "42"))
yields /friends?group=coworker&age=42.
Map keys and values representing parameter values are URL encoded by default. Specify encoded=true to change this behavior.
@GET("/friends")
Call<ResponseBody> friends(@QueryMap(encoded=true) Map<String, String> filters);
Calling with foo.list(ImmutableMap.of("group", "coworker+bowling"))
yields /friends?group=coworker+bowling.
QueryName
Simple Example:
@GET("/friends")
Call<ResponseBody> friends(@QueryName String filter);
Calling with foo.friends("contains(Bob)") yields /friends?contains(Bob).
Array/Varargs Example:
@GET("/friends")
Call<ResponseBody> friends(@QueryName String... filters);
Calling with foo.friends("contains(Bob)", "age(42)") yields /friends?contains(Bob)&age(42).
Parameter names are URL encoded by default. Specify encoded=true to change this behavior.
@GET("/friends")
Call<ResponseBody> friends(@QueryName(encoded=true) String filter);
Calling with foo.friends("name+age")) yields /friends?name+age.