kotlin协程在android的应用

  1. 可以让View层继承CoroutineScope by MainScope,就可以直接使用launch调用协程
abstract class BaseFragment:Fragment() ,CoroutineScope by MainScope(){
      fun xxx(){
          launch{
          //...业务逻辑,默认在主线程执行
          }
      }  
}
  1. 如果使用了ViewModle的话,可以在vm内直接使用viewModelScope.launch { }开启协程,也是在主线程内执行。
  2. 那么协程是怎么协的呢,举个栗子,retrofit网络请求,可以这样(注意这是举个栗子,实际开发用retrofit一般不会这么做,返回要么是Call,要么是Response,要么是Rxjava的Observable,否则服务端给个响应码404就异常了而且不好获取出错信息
    interface Api{
        @GET("xxx/xxx")
        suspend fun getData(): BaseDTO<*>
    }

    suspend fun getData() : BaseDTO<*> = withContext(Dispatchers.IO){
        Retrofit.Builder().baseUrl("").build().create(Api::class.java).getData()
    }
    
    fun test(){
        launch { 
            val data = getData() // getData是个suspend方法,withContext指定了运行在IO线程池
            refeshUI(data)// 回到launch下面,这里是运行在主线程的,可以拿到data后刷新UI
        }
    }

3.如果suspend不能直接返回结果呢,比如回调的时候怎么办?还是用retrofit举栗子

    interface Api{
        @GET("xxx/xxx")
        suspend fun getData(): BaseDTO<*>

        @GET("xxx/xxx")
        suspend  fun getData2():Call>
    }

   // 这个suspend方法一样能返回BaseDTO的数据
    suspend fun getData2() :BaseDTO<*>? = suspendCoroutine {continuation->
        val call = Retrofit.Builder().baseUrl("").build().create(Api::class.java).getData2()
        call.enqueue(object:Callback>{
            override fun onFailure(call: Call>, t: Throwable) {
                continuation.resume(null)
            }

            override fun onResponse(call: Call>, response: Response>) {
                continuation.resume(response.body())
            }

        })
    }
    fun test(){
        launch { 
            val data2 = getData2() // getData2是个suspend方法,withContext指定了运行在IO线程池
            refeshUI(data2)// 回到launch下面,这里是运行在主线程的,可以拿到data后刷新UI
        }
    }

协程的优势就是可以直接在一个花括号内,像写同步代码一样写异步代码,线程协作运行。一些不必要的LiveData、EventBus、Handler之类跳来跳去的通知可以省去了。

你可能感兴趣的:(kotlin协程在android的应用)