kotlin 协程 一

协程是什么? 协程基于线程,是轻量级的线程.
  • 处理耗时任务(这种任务常常会阻塞主线程)
  • 保证主线程安全(确保安全的从主线程调用任何的suspend函数).
// 模拟耗时操作,并更新ui.
lifecycleScope.launch { 
     delay(2000)  // 挂起当前协程2秒钟
     binding.tvText.setText(data)
 }

在这个实例中,我们使用了kotlin协程库,通过调用launch 函数创建了一个协程.并传入一个lambda表达式作为子线程中执行的代码块. 通过调用delay()函数模拟一个耗时操作,之后更新ui.

在协程中为什么可以直接更新ui?

在协程中更新ui的能力源于两个特征.

  • 挂起函数

协程支持挂起函数执行耗时操作,而不会阻塞线程.当执行挂起函数时,协程会挂起当前的执行,将线程还给调度器,让其他任务继续执行. 一旦挂起函数执行完毕,协程会自动恢复执行.并且在合适的时机将结果返回主线程. 这样可以避免了阻塞主线程,使得ui可以保持响应性.

  • 自动线程切换.

协程提供了自动的线程切换机制,可以方便在不同线程之间切换,通过合适的调度器配置,协程可以在需要的时候自动切换到主线程(比如使用Dispatchers.Main 调度器),以便在主线程更新ui. 这样耗时的操作可以在后台执行,并在完成之后自动切换到主线程进行ui更新,无需手动编写线程切换的逻辑.

lifecycleScope.launch() {
     withContext(Dispatchers.IO){
          Log.e("---","请求接口数据切换到IO线程---${Thread.currentThread().name}")
          "serviceData.."
     }.let {
          // 切换主线程,更新ui.
           withContext(Dispatchers.Main){
               binding.tvText.setText(it);
           }
      }
}

上面例子通过lifecycleScope.launch()开启了一个协程,模拟了耗时操作,并更新ui的过程.在第一个withContext代码块中,将调度器制定为IO,此时lambda代码中所有的操作都是在io线程中执行的. 拿到服务器数据之后,再次通过withContext代码块将调度器置定位Main,此时lambda代码就是在主线程中.

在第一个例子中,没有手动的执行withContext()函数为什么可以实现线程切换自由?这是因为 delay(),withContext(), suspendCancellableCoroutine(),都是挂起函数被 suspend 关键字修饰.

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容