【41】kotlin 协程 异步下载图片4 解决线程安全问题

我们的图片地址 是写死的。。但是为了防止出现线程安全问题

我们在async新建

ContextContinuation.kt

package com.yzdzy.kotlin.chapter7.async

import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext

/**
 * Created by benny on 5/29/17.
 */
class ContextContinuation(override val context: CoroutineContext = EmptyCoroutineContext): Continuation<Unit> {


    override fun resumeWith(result: Result<Unit>) {

    }

}

里面不做操作

修改

BaseCoroutines.kt
package com.yzdzy.kotlin.chapter7.basic

import cn.kotliner.coroutine.common.HttpError
import cn.kotliner.coroutine.common.HttpException
import cn.kotliner.coroutine.common.HttpService
import cn.kotliner.coroutine.common.log
import cn.kotliner.coroutine.ui.LOGO_URL
import com.yzdzy.kotlin.chapter7.async.*
import java.lang.Exception
import javax.swing.SwingUtilities
import kotlin.coroutines.*

fun 我要开始协程了(context: CoroutineContext=EmptyCoroutineContext,block: suspend () -> Unit) {
    block.startCoroutine(ContextContinuation(context + AsyncContext()))
}

suspend fun <T> 我要开始耗时操作了(block: CoroutineContext.() -> T) = suspendCoroutine<T> {  continuation ->
    AsyncTask {
        log("异步操作开始前")
//        try {
            val myContnet=continuation.context
            val myBlock=block(myContnet)
            continuation.resume(myBlock)
//        } catch (e: Exception) {
//            log("异步操作开始前e")
//            continuation.resumeWith(Result.failure(e))
//        }
    }.execute()
}


fun 我要开始加载图片了(url: String): ByteArray {
    log("下载图片开始")
    val reponseBody = HttpService.service.getLogo(url).execute()
    if (reponseBody.isSuccessful) {
        reponseBody.body()?.byteStream()?.readBytes()?.let {
            return it
        }
        throw HttpException(HttpError.HTTP_ERROR_NO_DATA)
    } else {
        //切换ui线程
        throw HttpException(reponseBody.code())
    }

}

新建

DownloadContext.kt

package com.yzdzy.kotlin.chapter7.async

import kotlin.coroutines.AbstractCoroutineContextElement
import kotlin.coroutines.CoroutineContext

class DownloadContext (val url:String):AbstractCoroutineContextElement(Key){
    companion object Key:CoroutineContext.Key<DownloadContext>

}

修改 MainKt.kt

package cn.kotliner.coroutine.ui


import cn.kotliner.coroutine.common.HttpError
import cn.kotliner.coroutine.common.HttpService
import cn.kotliner.coroutine.common.log
import com.yzdzy.kotlin.chapter7.async.AsyncTask
import com.yzdzy.kotlin.chapter7.async.DownloadContext
import com.yzdzy.kotlin.chapter7.basic.我要开始加载图片了
import com.yzdzy.kotlin.chapter7.basic.我要开始协程了
import com.yzdzy.kotlin.chapter7.basic.我要开始耗时操作了
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.HttpException
import retrofit2.Response
import java.lang.Exception
import javax.swing.JFrame.EXIT_ON_CLOSE
import javax.swing.SwingUtilities

/**
 * Created by benny on 5/20/17.
 */
const val LOGO_URL = "http://www.imooc.com/static/img/index/logo.png?t=1.1"

fun main(args: Array<String>) {
    val frame = MainWindow()
    frame.title = "Coroutine@Bennyhuo"
    frame.setSize(200, 150)
    frame.isResizable = true
    frame.defaultCloseOperation = EXIT_ON_CLOSE
    frame.init()
    frame.isVisible = true

    frame.onButtonClick {

        log("协程之前")
        我要开始协程了(DownloadContext(LOGO_URL)) {
            //为了防止出错。我们一般要做一次异常捕获。这也是协程的好处 只用一次try就好了
            try {
                log("协程开始")
                val imageDate = 我要开始耗时操作了{
                    log(this[DownloadContext]!!.url)
                    我要开始加载图片了(this[DownloadContext]!!.url)
                }
                log("拿到图片")
                frame.setLogo(imageDate)
            }catch (e:Exception){
                e.printStackTrace()
            }

        }
        log("协程之后")
    }


}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安果移不动

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值