依赖
// Retrofit 依赖
implementation ("com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2")
// Retrofit的一个转换器,使用Gson库来序列化和反序列化JSON数据。
implementation ("com.squareup.retrofit2:converter-gson:2.9.0")
DTO
请求验证码的DTO
data class GetCodeRequestDTO(var phone: String) {
}
data class GetCodeResponseDTO(val code:Int,val msg:String,val data:String) {
}
请求登录的DTO
data class LoginRequestDTO(val phone: String,val smsCode: String) {
}
data class LoginResponseDTO(val code:Int,val msg:String,val data:String) {
}
Api接口
Deferred
是 Kotlin
协程中的一种类型,表示一个可能在未来某个时刻完成的计算或异步操作的结果。Deferred
通常用于需要返回结果的异步操作中。
- await(): 一个挂起函数,用于等待 Deferred 完成并返回结果。如果 Deferred 完成时抛出了异常,await() 会将这个异常重新抛出。
- cancel(): 可以取消与 Deferred 关联的协程。
interface LoginApiService {
@POST("weibo/api/auth/login")
fun requestLogin(@Body loginRequest: LoginRequest): Deferred<LoginResponse>
}
interface GetCodeApiService {
@POST("weibo/api/auth/sendCode")
fun requestGetCode(@Body sendCodeRequest: SendCodeRequest): Deferred<GetCodeResponse>
}
Retrofit类
将HTTP API
转换成Java
接口
使用lazy
修饰的属性在第一次被访问时才会进行初始化,而不是在创建宿主对象时立即初始化。
import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object RetrofitClient {
private const val BASE_URL = "https://XXX.XXX.XXX/"
// 创建 共享Retrofit 实例
private val retrofit: Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.build()
// 创建 GetCodeApiService 的实例
val getCodeApiService: GetCodeApiService by lazy {
retrofit.create(GetCodeApiService::class.java)
}
// 创建 LoginApiService 的实例
val getLoginApiService: LoginApiService by lazy {
retrofit.create(LoginApiService::class.java)
}
}
协程发送请求
这里以viewLifecycleOwner.lifecycleScope.launch
的方式启动协程,viewLifecycleOwner.lifecycleScope.launch
结合了 lifecycleScope
的生命周期感知能力和 launch
的协程启动功能,是Android
协程编程中推荐的做法之一。
await()
是 Kotlin
协程中一个非常重要的挂起函数(suspend function
),它用于等待一个异步操作完成。在协程的世界里,await()
通常与 Deferred
对象一起使用,正如前面所言,Deferred
是一个代表了未来某个时刻会完成的计算结果的容器。
请求验证码的函数
private fun requestVerificationCode(phoneNumber: String) {
// 创建了一个新的协程作用域
viewLifecycleOwner.lifecycleScope.launch {
try {
// 实例化一下传的参数
sendCodeRequest = SendCodeRequest(phoneNumber)
// 获取 Retrofit 配置的 API 服务接口实例
val apiService = RetrofitClient.getCodeApiService
// 直接在lifecycleScope.launch中调用挂起函数
val response = apiService.requestGetCode(sendCodeRequest!!).await() // 等待Deferred完成并获取结果
Log.d(TAG, "requestVerificationCode: $response")
// 这里可以继续处理响应结果
} catch (e: Exception) { // 捕获异常,例如网络错误或序列化问题
Log.d(TAG, "requestVerificationCode: ${e.message}")
// 这里可以处理异常,例如显示错误信息给用户
}
}
}
求登录的函数
// 请求登录
private fun requestLogin(phoneNumber: String,codeNumber:String) {
// 创建了一个新的协程作用域
viewLifecycleOwner.lifecycleScope.launch {
try {
// 实例化一下传的参数
loginRequest = LoginRequest(phoneNumber,codeNumber)
// 获取 Retrofit 配置的 API 服务接口实例
val apiService = RetrofitClient.getLoginApiService
// 直接在lifecycleScope.launch中调用挂起函数
val response = apiService.requestLogin(loginRequest!!).await() // 等待Deferred完成并获取结果
Toast.makeText(context, "登录成功", Toast.LENGTH_LONG).show()
// 这里可以继续处理响应结果
} catch (e: Exception) { // 捕获异常,例如网络错误或序列化问题
Log.d(TAG, "requestVerificationCode: ${e.message}")
// 这里可以处理异常,例如显示错误信息给用户
}
}
}