1.講解異常之前先寫這樣一個(gè)例子
需求異步操作獲取用戶,主界面展示用戶信息,怎么樣用協(xié)程的方式去寫
typealias CallBack=(User)->Unit
fun getUser(callback: CallBack){
thread {
log(1)
var user=User("he",23)
callback.invoke(user)
}
}
suspend fun getUserCoroutine()= suspendCoroutine<User> {
continuation->
getUser {
continuation.resume(it)
}
}
suspend fun main(){
GlobalScope.launch (Dispatchers.Main){
val name = getUserCoroutine().name
val age = getUserCoroutine().age
log(name+age)
}.join()
}
思考如果獲取user的過(guò)程中有異常出現(xiàn)怎么處理,比如name為空字符串的user視為異常
interface MyCallBack<T>{
fun onSuccess(value:T)
fun onError(t:Throwable)
}
fun getUserWithError(callback: MyCallBack<User>){
//模擬異步操作
thread {
log(1)
var user=User("",23)
if (user.name.isEmpty()){
callback.onError(Throwable("姓名為空"))
}else{
callback.onSuccess(user)
}
}
}
suspend fun getUserCoroutineWithError()= suspendCoroutine<User> {
continuation->
getUserWithError(object :MyCallBack<User>{
override fun onSuccess(value: User) {
continuation.resume(value)
}
override fun onError(t: Throwable) {
continuation.resumeWithException(t)
}
})
}
suspend fun main(){
GlobalScope.launch {
try {
val user = getUserCoroutineWithError()
log(user.name)
}catch (t:Throwable){
log(t)
}
}.join()
}
從上面的代碼我們可以看出一個(gè)異步的請(qǐng)求異常,我們只需要在協(xié)程里面try奉呛,catch就可以了
這個(gè)時(shí)候我們?cè)偃タ撮_篇協(xié)程實(shí)現(xiàn)retrofit請(qǐng)求,就理解為什么可以這樣子寫
GlobalScope.launch {
try {
val weatherEntity = apiService.getMessage3("鄭州")
println(weatherEntity.temperature)
}catch (e:Throwable){
println(e.message)
}
}
還有一種異常捕獲方式夯尽,不需要寫try瞧壮,catch
suspend fun main(){
val coroutineExceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
log(throwable)
}
GlobalScope.launch(coroutineExceptionHandler) {
val user = getUserCoroutineWithError()
log(user.name)
}.join()
}
CoroutineExceptionHandler 同樣也是協(xié)程上下文,但是不適用于async啟動(dòng)的協(xié)程