Retrofit 使用

基本用法

Retrofit 地址

先添加依赖:

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

创建接口文件:

interface AppService {

@GET("get_data.json")
fun getAppData(): Call<List<App>>
}

通常 Retrofit 的接口文件以具体的功能种类名开头,并以 Service 结尾。

val retrofit = Retrofit.Builder()
.baseUrl("http://10.0.2.2/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val appService = retrofit.create(AppService::class.java)
appService.getAppData().enqueue(object : Callback<List<App>> {
override fun onResponse(call: Call<List<App>>, response: Response<List<App>>) {
val list = response.body()
if (list != null) {
for (app in list) {
Log.d(TAG, "id is ${app.id}")
Log.d(TAG, "name is ${app.name}")
Log.d(TAG, "version is ${app.version}")
}
}
}

override fun onFailure(call: Call<List<App>>, t: Throwable) {
t.printStackTrace()
}

})

处理复杂的接口地址类型

@GET("get_data.json")
fun getAppData(): Call<List<App>>

// 传入不同的页数
@GET("{page}/get_data.json")
fun getData(@Path("page") page: Int): Call<Data>

// 传入参数 GET http://example.com/get_data.json?u=<user>&t=<token>
@GET("get_data.json")
fun getData(@Query("u") user: String, @Query("t") token: String): Call<Data>

// 删除接口 DELETE http://example.com/data/<id>
// ResponseBody表示能够接收任何类型的响应数据并不会解析
@DELETE("data/{id}")
fun deleteData(@Path("id") id: String): Call<ResponseBody>

// POST http://example.com/data/create
// {"id":1,"content":"The description for this data."}
@POST("data/create")
fun createData(@Body data: Data): Call<ResponseBody>

/** 静态声明header
* GET http://example.com/get_data.json
* User-Agent: okhttp
* Cache-Control: max-age=0
**/
@Headers("User-Agent: okhttp", "Cache-Control: max-age=0")
@GET("get_data.json")
fun getData(): Call<Data>

// 动态声明header
@GET("get_data.json")
fun getData2(
@Header("User-Agent") userAgent: String,
@Header("Cache-Control") cacheControl: String
): Call<Data>

代码封装

ServiceCreator
object ServiceCreator {

private const val BASE_URL = "https://api.caiyunapp.com/"

private val client = OkHttpClient.Builder().addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}).build()

private val retrofit = Retrofit.Builder()
.client(client)
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()

fun <T> create(serviceClass: Class<T>): T = retrofit.create(serviceClass)

inline fun <reified T> create(): T = create(T::class.java)
}

// 使用:
val appService = ServiceCreator.create<AppService>()
XxxNetwork
object XxxNetwork {
private suspend fun <T> Call<T>.await(): T {
return suspendCoroutine { continuation ->
enqueue(object : Callback<T> {
override fun onResponse(call: Call<T>, response: Response<T>) {
val body = response.body()
if (body != null) continuation.resume(body)
else continuation.resumeWithException(RuntimeException("response body is null"))
}

override fun onFailure(call: Call<T>, t: Throwable) {
continuation.resumeWithException(t)
}
})
}
}
}

参考