【问题标题】:How to handle Coroutines jobs如何处理协程作业
【发布时间】:2022-12-20 17:55:02
【问题描述】:

我有一个有方法的视图模型。有 4 个条件基于 4 个按钮,每个条件可以通过此方法中的 viewModelScope 单独运行。 现在我想分别停止并重新启动每个 viewModelScope,但我不知道该怎么做。 当我通过 job1.cancel() 取消 viewModelScope 时,我无法再次启动它。

这是我要处理的代码:

fun calculateDistance(tripId: Int) = viewModelScope.launch {
    var currentCost: Double = 6500.0
    var partCost: Double = 0.0
    while (isActive) {
        localRepository.getUnCalculatedLocation(tripId).collect { result ->
            if (result.data!!.isNotEmpty()) {
                result.data.forEach {

                    var passId = 0
                    val distance = Calculates.distance(
                        lat1 = if (it.latitude1 != 0.0) it.latitude1 else it.latitudeNet1,
                        lat2 = if (it.latitude2 != 0.0) it.latitude2 else it.latitudeNet2,
                        long1 = if (it.longitude1 != 0.0) it.longitude1 else it.longitudeNet1,
                        long2 = if (it.longitude2 != 0.0) it.longitude2 else it.longitudeNet2
                    )
                    localRepository.getPassId(it.tripId!!.toInt()).collect { id ->
                        if (id.data != null) {
                            passId = id.data
                        }
                    }
                    var passDistance = PassengerDistance(passId, distance)
                    _passDistance.postValue(passDistance)
                    localRepository.updateLocation(distance, it.id)

                   
                    var uniqueId = ""
                    localRepository.getUniqueId(it.tripId).collect { uid ->
                        uniqueId = uid.data!!
                    }
                    when (passId) {
                        1 -> {

                            job1.launch {
                                _tripTime1.postValue(_tripTime1.value?.plus(2000))
                                if (distance == 0.0) {
                                    if (secondCost1 < 10) secondCost1 += 2
                                    else {
                                        val expression: Expression =
                                            Expression(_formula.value?.stoppingFormula)
                                        val resultCost: EvaluationValue =
                                            expression.with("T", secondCost1).evaluate()
                                        currentCost =
                                            if (_costPass1.value == null) constCost.toDouble() else _costPass1.value!!

                                        partCost = resultCost.numberValue.toDouble()

                                        _costPass1.postValue(resultCost.numberValue.toDouble() + currentCost)
                                        secondCost1 = 0
                                    }

                                } else {
                                    val expression: Expression =
                                        Expression(_formula.value?.movingFormula)
                                    val resultCost: EvaluationValue =
                                        expression.with("D", distance * 1000).evaluate()
                                    val resultTest = (2109 / 200) * distance
                                    currentCost =
                                        if (_costPass1.value == null) constCost.toDouble() else _costPass1.value!!
                                    partCost = resultCost.numberValue.toDouble()
                                    var two = partCost * 2
                                    Log.d(
                                        "DISTANCE",
                                        "actual cost is $partCost , Test: $resultTest"
                                    )
                                    _costPass1.postValue((resultCost.numberValue.toDouble() * 2) + currentCost)

                                    _tripDistance1.postValue(
                                        _tripDistance1.value?.plus(
                                            distance
                                        )
                                    )

                                }


                                localRepository.updateCurrentCost(partCost, it.id!!)


                                val saveLocation = TripDetails(
                                    id = it.id,
                                    latitude1 = it.latitude1,
                                    latitude2 = it.latitude2,
                                    longitude1 = it.longitude1,
                                    longitude2 = it.longitude2,
                                    accuracy1 = it.accuracy1,
                                    accuracy2 = it.accuracy2,
                                    latitudeNet1 = it.latitudeNet1,
                                    latitudeNet2 = it.latitudeNet2,
                                    longitudeNet1 = it.longitudeNet1,
                                    longitudeNet2 = it.longitudeNet2,
                                    accuracy1Net = it.accuracy1Net,
                                    accuracy2Net = it.accuracy2Net,
                                    tripId = it.tripId,
                                    distance = distance,
                                    isCalculated = true,
                                    isEnded = it.isEnded,
                                    date = it.date,
                                    cost = partCost,
                                    uniqueId = uniqueId,
                                    isMonitor = _isMonitor.value!!,
                                    driverId = _driver.value?.data?.driverId!!
                                )
                                try {
                                    repository.saveLocation(saveLocation).let { result ->
                                        if (result.isSuccessful) {
                                            Log.d("TAG", result.body()?.result.toString())
                                        } else {
                                            Log.d("TAG", result.body()?.message!!)
                                        }
                                    }
                                } catch (e: Exception) {
                                    Log.d("Error", e.message.toString())
                                }
                            }

                        }


                        2 -> {
                            job2.launch {
                                _tripTime2.postValue(_tripTime2.value?.plus(2000))
                                if (distance == 0.0) {
                                    if (secondCost2 < 10) secondCost2 += 2
                                    else {
                                        val expression: Expression =
                                            Expression(_formula.value?.stoppingFormula)
                                        val resultCost: EvaluationValue =
                                            expression.with("T", secondCost2).evaluate()
                                        currentCost =
                                            if (_costPass2.value == null) constCost.toDouble() else _costPass2.value!!
                                        _costPass2.postValue(resultCost.numberValue.toDouble() + currentCost)
                                        partCost = resultCost.numberValue.toDouble()
                                        secondCost2 = 0
                                    }

                                } else {
                                    val expression: Expression =
                                        Expression(_formula.value?.movingFormula)
                                    val resultCost: EvaluationValue =
                                        expression.with("D", distance * 1000).evaluate()
                                    currentCost =
                                        if (_costPass2.value == null) constCost.toDouble() else _costPass2.value!!
                                    _costPass2.postValue(resultCost.numberValue.toDouble() + currentCost)
                                    partCost = resultCost.numberValue.toDouble()
                                    _tripDistance2.postValue(_tripDistance2.value?.plus(distance))

                                }

                                val saveLocation = TripDetails(
                                    id = it.id,
                                    latitude1 = it.latitude1,
                                    latitude2 = it.latitude2,
                                    longitude1 = it.longitude1,
                                    longitude2 = it.longitude2,
                                    accuracy1 = it.accuracy1,
                                    accuracy2 = it.accuracy2,
                                    latitudeNet1 = it.latitudeNet1,
                                    latitudeNet2 = it.latitudeNet2,
                                    longitudeNet1 = it.longitudeNet1,
                                    longitudeNet2 = it.longitudeNet2,
                                    accuracy1Net = it.accuracy1Net,
                                    accuracy2Net = it.accuracy2Net,
                                    tripId = it.tripId,
                                    distance = distance,
                                    isCalculated = true,
                                    isEnded = it.isEnded,
                                    date = it.date,
                                    cost = partCost,
                                    uniqueId = uniqueId,
                                    isMonitor = _isMonitor.value!!,
                                    driverId = _driver.value?.data?.driverId!!
                                )
                                try {
                                    repository.saveLocation(saveLocation).let { result ->
                                        if (result.isSuccessful) {
                                            Log.d("TAG", result.body()?.result.toString())
                                        } else {
                                            Log.d("TAG", result.body()?.message!!)
                                        }
                                    }
                                } catch (e: Exception) {
                                    Log.d("Error", e.message.toString())
                                }
                            }

                        }

                        3 -> {
                            job3.launch {
                                _tripTime3.postValue(_tripTime3.value?.plus(2000))
                                if (distance == 0.0) {
                                    if (secondCost3 < 10) secondCost3 += 2
                                    else {
                                        val expression: Expression =
                                            Expression(_formula.value?.stoppingFormula)
                                        val resultCost: EvaluationValue =
                                            expression.with("T", secondCost3).evaluate()
                                        currentCost =
                                            if (_costPass3.value == null) constCost.toDouble() else _costPass3.value!!
                                        _costPass3.postValue(resultCost.numberValue.toDouble() + currentCost)
                                        partCost = resultCost.numberValue.toDouble()
                                        secondCost3 = 0
                                    }

                                } else {
                                    val expression: Expression =
                                        Expression(_formula.value?.movingFormula)
                                    val resultCost: EvaluationValue =
                                        expression.with("D", distance * 1000).evaluate()
                                    currentCost =
                                        if (_costPass3.value == null) constCost.toDouble() else _costPass3.value!!
                                    _costPass3.postValue(resultCost.numberValue.toDouble() + currentCost)
                                    partCost = resultCost.numberValue.toDouble()
                                    _tripDistance3.postValue(_tripDistance3.value?.plus(distance))

                                }

                                val saveLocation = TripDetails(
                                    id = it.id,
                                    latitude1 = it.latitude1,
                                    latitude2 = it.latitude2,
                                    longitude1 = it.longitude1,
                                    longitude2 = it.longitude2,
                                    accuracy1 = it.accuracy1,
                                    accuracy2 = it.accuracy2,
                                    latitudeNet1 = it.latitudeNet1,
                                    latitudeNet2 = it.latitudeNet2,
                                    longitudeNet1 = it.longitudeNet1,
                                    longitudeNet2 = it.longitudeNet2,
                                    accuracy1Net = it.accuracy1Net,
                                    accuracy2Net = it.accuracy2Net,
                                    tripId = it.tripId,
                                    distance = distance,
                                    isCalculated = true,
                                    isEnded = it.isEnded,
                                    date = it.date,
                                    cost = partCost,
                                    uniqueId = uniqueId,
                                    isMonitor = _isMonitor.value!!,
                                    driverId = _driver.value?.data?.driverId!!
                                )
                                try {
                                    repository.saveLocation(saveLocation).let { result ->
                                        if (result.isSuccessful) {
                                            Log.d("TAG", result.body()?.result.toString())
                                        } else {
                                            Log.d("TAG", result.body()?.message!!)
                                        }
                                    }
                                } catch (e: Exception) {
                                    Log.d("Error", e.message.toString())
                                }
                            }

                        }

                        4 -> {
                            job4.launch {
                                _tripTime4.postValue(_tripTime4.value?.plus(2000))
                                if (distance == 0.0) {
                                    if (secondCost4 < 10) secondCost4 += 2
                                    else {
                                        val expression: Expression =
                                            Expression(_formula.value?.stoppingFormula)
                                        val resultCost: EvaluationValue =
                                            expression.with("T", secondCost4).evaluate()
                                        currentCost =
                                            if (_costPass4.value == null) constCost.toDouble() else _costPass4.value!!
                                        _costPass4.postValue(resultCost.numberValue.toDouble() + currentCost)
                                        partCost = resultCost.numberValue.toDouble()
                                        secondCost4 = 0
                                    }

                                } else {
                                    val expression: Expression =
                                        Expression(_formula.value?.movingFormula)
                                    val resultCost: EvaluationValue =
                                        expression.with("D", distance * 1000).evaluate()
                                    currentCost =
                                        if (_costPass4.value == null) constCost.toDouble() else _costPass4.value!!
                                    _costPass4.postValue(resultCost.numberValue.toDouble() + currentCost)

                                    partCost = resultCost.numberValue.toDouble()
                                    _tripDistance4.postValue(_tripDistance4.value?.plus(distance))

                                }

                                val saveLocation = TripDetails(
                                    id = it.id,
                                    latitude1 = it.latitude1,
                                    latitude2 = it.latitude2,
                                    longitude1 = it.longitude1,
                                    longitude2 = it.longitude2,
                                    accuracy1 = it.accuracy1,
                                    accuracy2 = it.accuracy2,
                                    latitudeNet1 = it.latitudeNet1,
                                    latitudeNet2 = it.latitudeNet2,
                                    longitudeNet1 = it.longitudeNet1,
                                    longitudeNet2 = it.longitudeNet2,
                                    accuracy1Net = it.accuracy1Net,
                                    accuracy2Net = it.accuracy2Net,
                                    tripId = it.tripId,
                                    distance = distance,
                                    isCalculated = true,
                                    isEnded = it.isEnded,
                                    date = it.date,
                                    cost = partCost,
                                    uniqueId = uniqueId,
                                    isMonitor = _isMonitor.value!!,
                                    driverId = _driver.value?.data?.driverId!!
                                )
                                try {
                                    repository.saveLocation(saveLocation).let { result ->
                                        if (result.isSuccessful) {
                                            Log.d("TAG", result.body()?.result.toString())
                                        } else {
                                            Log.d("TAG", result.body()?.message!!)
                                        }
                                    }
                                } catch (e: Exception) {
                                    Log.d("Error", e.message.toString())
                                }
                            }

                        }
                    }

                }
            }

        }
        delay(2000)
    }

}

这里有一个 when 语句,它有 4 个条件。每个条件有 4 个按钮。 一个

【问题讨论】:

  • 如果您取消了工作,只需创建一个新工作,这是设计使然。

标签: android kotlin kotlin-coroutines android-viewmodel


【解决方案1】:

代码很复杂。很难理解工作流程。

如果您想为该阶段运行一个新作业并由于某种原因取消它。 您必须为每个阶段创建一个新作业。

1 -> {
    job1 = viewModelScope.launch {
...
4 -> {
    job4 = viewModelScope.launch {

【讨论】:

    猜你喜欢
    • 2012-03-24
    • 1970-01-01
    • 2020-01-07
    • 2023-01-09
    • 2010-11-05
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    相关资源
    最近更新 更多