Android 不启动挂起功能的全局标志?

Android 不启动挂起功能的全局标志?,android,kotlin,kotlin-coroutines,Android,Kotlin,Kotlin Coroutines,我需要启动方法getFuelPrice,前提是之前没有启动。为此,我使用全局标志isStartGetFuelPrice smt是这样的: for (currentPass in 0..10) { // some code here viewModelScope.launch(Dispatchers.Main) { if (!isStartedGetFuelPrice) { currentCheck = getFuelPrice(currentCheck)

我需要启动方法
getFuelPrice
,前提是之前没有启动。为此,我使用全局标志
isStartGetFuelPrice

smt是这样的:

for (currentPass in 0..10) {  
 // some code here  
viewModelScope.launch(Dispatchers.Main) {
   if (!isStartedGetFuelPrice) {
      currentCheck = getFuelPrice(currentCheck)
                       }
                                    }
}
在迭代1中,方法
getFuelPrice
开始,但在迭代2中不得开始。函数
getFuelPrice
只能调用一次

这是:

suspend fun getFuelPrice(currentRecognizedCheck: Check): Check {

        isStartedGetFuelPrice = true
// some logic here
isStartedGetFuelPrice = false
        return currentRecognizedCheck

但我认为全球旗帜不是一个好的解决方案。还有其他更好的方法吗?

对于并发代码,确实不建议使用全局可变共享状态

不过,您可以尝试以下方法:

data class Once(private val block: suspend () -> Unit) {
    private val ran = AtomicBoolean(false)
    suspend fun run() {
        if (ran.compareAndSet(false, true)) {
            block()
        }
    }
}
然后:

您还可以让
一次
返回一个值,但为此,您需要使用Kotlin
互斥体

data class Once<out T : Any>(private val block: suspend () -> T) {
    private val mutex = Mutex()
    private lateinit var r : T

    suspend fun run(): T {
        mutex.lock()
        if (!this::r.isInitialized) {
            r = block()
        }
        mutex.unlock()
        return r
    }
}
如果您不喜欢互斥体,还有另一个窍门:

class Once<T>(block: suspend () -> T) {
    private val r = GlobalScope.async(start = CoroutineStart.LAZY) {
        block()
    }

    suspend fun run() = r.await()
}
类一次(块:suspend()->T){
private val r=GlobalScope.async(start=CoroutineStart.LAZY){
块()
}
suspend fun run()=r.await()
}

是否要按顺序调用此函数11次,每次都等待结果?代码中是否还有其他地方可以调用
getFuelPrice()
,并且还需要这些调用来等待轮到它们?如果是这样,那么另一个函数应该等待它准备好还是放弃呢?@Tenfour04只在这里调用getFuelPrice()。我只想调用一次函数getFuelPrice()。那么什么是
for(currentPass in 0..10)
for?@Tenfour04循环需要其他东西。我不明白。如果你只想调用它一次,为什么不把它移出循环呢?或者如果(currentPass==0){}将其包装在
中?假设
getFuelPrice
必须是一个挂起函数,您还需要将
block
run()
标记为
suspend
@AlexeySohin getFuelPrice必须返回我的自定义对象检查
suspend fun run(): T {
    return mutex.withLock {
        if (!this::r.isInitialized) {
            r = block()
        }
        r
    }
}
class Once<T>(block: suspend () -> T) {
    private val r = GlobalScope.async(start = CoroutineStart.LAZY) {
        block()
    }

    suspend fun run() = r.await()
}