协程与retrofit结合使用
- 创建service,返回类型为自定义response
@POST("...")
suspend fun login1(
@Path("login") login: String,
@Body body: RSRfLoginRequest
): BaseResponse<RSRfLoginResponse>
class BaseResponse<T>(val success: Boolean = false, val code: Int, val data: T? = null, val message: String? = null)
- 创建Repository,此处为了测试加了2秒延迟
suspend fun login1(login: String, req: RSRfLoginRequest): BaseResponse<RSRfLoginResponse> {
return withContext(Dispatchers.IO) {
delay(2000)
remote.login1(login, req)
}
}
suspend fun login1() = repo.login1("", RSRfLoginRequest().apply {
})
- 初始化协程作用域,CoroutineScope跟随activity,在destory是调用取消,即activity销毁时协程也会停止,不会继续执行没有执行完毕的任务
class MainActivity : BaseActivity<ActivityMainBinding>(),
CoroutineScope by CoroutineScope(Dispatchers.Main) {
override fun onDestroy() {
super.onDestroy()
cancel()
}
- view层调用,此处使用scope.launch开启协程,里面login1是挂起函数
private fun initData1() {
launch {
try {
val result = mViewModel.login1()
when (result.success) {
true -> {
Toast.makeText(this@MainActivity, "成功", Toast.LENGTH_SHORT).show()
}
false -> {
Toast.makeText(this@MainActivity, "失败", Toast.LENGTH_SHORT).show()
}
}
} catch (e: Exception) {
Toast.makeText(this@MainActivity, e.message, Toast.LENGTH_SHORT).show()
}
}
}
协程多个请求并行
- 使用了async 关键字开启子协程,并用await获取返回值
private fun initData2() {
launch {
try {
val result1 = async { mViewModel.login1() }
val result2 = async { mViewModel.login1() }
val data1 = result1.await()
val data2 = result2.await()
when (data1.success) {
true -> {
Toast.makeText(this@MainActivity, "data1成功", Toast.LENGTH_SHORT).show()
Log.d(localClassName, "data1成功")
}
false -> {
Toast.makeText(this@MainActivity, "data1失败", Toast.LENGTH_SHORT).show()
Log.d(localClassName, "data1失败")
}
}
when (data2.success) {
true -> {
Toast.makeText(this@MainActivity, "data2成功", Toast.LENGTH_SHORT).show()
Log.d(localClassName, "data2成功")
}
false -> {
Toast.makeText(this@MainActivity, "data2失败", Toast.LENGTH_SHORT).show()
Log.d(localClassName, "data2失败")
}
}
} catch (e: Exception) {
Toast.makeText(this@MainActivity, e.message, Toast.LENGTH_SHORT).show()
}
}
}
协程多个请求串行
private fun initData3() {
launch {
try {
val data1 = mViewModel.login1()
val data2 = mViewModel.login1()
when (data1.success) {
true -> {
Toast.makeText(this@MainActivity, "data1成功", Toast.LENGTH_SHORT).show()
Log.d(localClassName, "data1成功")
}
false -> {
Toast.makeText(this@MainActivity, "data1失败", Toast.LENGTH_SHORT).show()
Log.d(localClassName, "data1失败")
}
}
when (data2.success) {
true -> {
Toast.makeText(this@MainActivity, "data2成功", Toast.LENGTH_SHORT).show()
Log.d(localClassName, "data2成功")
}
false -> {
Toast.makeText(this@MainActivity, "data2失败", Toast.LENGTH_SHORT).show()
Log.d(localClassName, "data2失败")
}
}
} catch (e: Exception) {
Toast.makeText(this@MainActivity, e.message, Toast.LENGTH_SHORT).show()
}
}
}
协程 launch 和 async 区别
- launch 更多是用来发起一个无需结果的耗时任务,这个工作不需要返回结果
- async 函数则是更进一步,用于异步执行耗时任务,并且需要返回值(如网络请求、数据库读写、文件读写),在执行完毕通过 await() 函数获取返回值
- 在概念上,async 就类似于 launch。它启动了一个单独的协程与其它所有的协程一起并发的工作。不同之处在于 launch 返回一个 Job 并且不附带任何结果值,而 async 返回一个 Deferred ——> 一个非阻塞 future, 这代表了一个将会在稍后提供结果的 promise。你可以使用 .await()在一个延期的值上得到它的最终结果, 但是 Deferred 也是一个 Job,所以如果需要的话,你可以取消它
|