Kotlin学习——简单运用协程网络下载图片并更新到UI

kotlin学习

协程Coroutines学习


简单小Demo:通过协程下载一张网络图片并显示出来


前言

我们所有的代码都是跑在线程中的,而线程是跑在进程中的。 协程没有直接和操作系统关联,但它不是空中楼阁,它也是跑在线程中的,可以是单线程,也可以是多线程。 单线程中的协程总的执行时间并不会比不用协程少。 Android 系统上,如果在主线程进行网络请求,会抛出 NetworkOnMainThreadException,对于在主线程上的协程也不例外,这种场景使用协程还是要切线程的 。

一、如何开启一个协程?

协程是跑在线程里的

launch {

......

}

用以上launch函数可以开启一个协程,但是launch并不是顶层函数。有以下三种方法来创建协程

// 方法一,使用 runBlocking 顶层函数
runBlocking {
   
    getImage(imageId)
}

// 方法二,使用 GlobalScope 单例对象
//            👇 可以直接调用 launch 开启协程
GlobalScope.launch {
   
    getImage(imageId)
}

// 方法三,自行通过 CoroutineContext 创建一个 CoroutineScope 对象
//                                    👇 需要一个类型为 CoroutineContext 的参数
val coroutineScope = CoroutineScope(context)
coroutineScope.launch {
   
    getImage(imageId)
}

第一种方法不推荐,因为它是线程堵塞的

第二种方法创建的协程生命周期会和APP的一样,不适合执行后台任务

第三种较为推荐,可以通过context参数来管理和控制协程的生命周期

运用协程可以方便的进行线程的切换

//切换到IO线程
coroutineScope.launch(Dispatchers.IO) {
   
    ...
}
//切换到主线程
coroutineScope.launch(Dispatchers.Main) {
   
    ...
}

但是以下的一种场景,如果在IO线程进行了网络请求获得数据需要在主线程更行UI界面,操作需要切换回主线程。这时候就会出现嵌套操作,如何解决呢?如果只是使用launch函数,协程并不能比线程完成更多操作,但是协程提供了一个很实用的函数withContext()

这个函数可以切换到指定的线程,并且执行完后自动返回执行之前的线程

coroutineScope.launch(Dispatchers.Main) {
         // 👈 在 UI 线程开始
    val image = withContext(Dispatchers.IO) {
     // 👈 切换到 IO 线程,并在执行完成后切回 UI 线程
        getImage(imageId)                      // 👈 将会运行在 IO 线程
    }
    avatarIv.setImageBitmap
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值