我想在不可组合的后台线程中调用可组合组件

问题描述 投票:0回答:1

会话管理器:

class SessionManager @Inject constructor(@ApplicationContext private val context: Context) :
    SessionService {

    val openAlert = mutableStateOf(false)
    val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "user_preferences")
    private val accessToken = stringPreferencesKey("accessToken")
    override suspend fun saveToken(token: String, navController: NavController): Boolean {
        try {
            context.dataStore.edit { settings ->
                settings[accessToken] = token
            }

        } catch (e: Exception) {
            return false
        } finally {
            StartSession(navController)
        }
        return true
    }

    override suspend fun getToken() = context.dataStore.data.map { preferences ->
        preferences[accessToken] ?: ""
    }

    override suspend fun validateSession(token: String): Boolean {
        TODO("Not yet implemented")
    }

    override suspend fun invalidateSession(token: String): Boolean {
        TODO("Not yet implemented")
    }

    override suspend fun extendSession(token: String): Boolean {
        TODO("Not yet implemented")
    }

    override suspend fun StartSession(navController: NavController) {
        withContext(Dispatchers.Default) {
            // Simulate a time-consuming task
            //delay(3000)
            // Update the result on the main (UI) thread

            withContext(Dispatchers.Main) {
               // result = "Task completed"
                PreShared()
                //I want to call the composible object here
            }
        }

            Log.w("SessionTimer", "Session Started : " )



       // }
    }

}

背景倒数计时器:

class BackgroundCountDownTimer(
    totalTime: Long,
    interval: Long,
    private val listener: CountdownListener
) {
    private val scheduler: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
    private val countDownLatch = CountDownLatch(1)
    private var remainingTime = totalTime

    interface CountdownListener {
        fun onTick(secondsRemaining: Long)
        fun onFinish(onSuccess: () -> Unit = {})
        fun openAlert()

    }

    init {
        scheduler.scheduleAtFixedRate({
            if (remainingTime > 0) {
                listener.onTick(remainingTime)
                remainingTime -= interval
            } else {
                listener.onFinish(onSuccess = {
                    listener.openAlert()
                })
                countDownLatch.countDown()
                scheduler.shutdown()
            }
        }, 0, interval, TimeUnit.MILLISECONDS)
    }

    fun awaitCompletion() {
        try {
            countDownLatch.await()
        } catch (e: InterruptedException) {
            e.printStackTrace()
        }
    }

}

可组合:

@Composable
fun PreShared(){

}
kotlin android-jetpack-compose
1个回答
0
投票

您无法在可组合范围之外调用可组合函数。

如果您只需要在可组合项显示之前等待固定的时间,您可以按如下方式执行:

@Composable
fun MainComposable() {
    var timerFinished by remember { mutableStateOf(false) }

    LaunchedEffect(Unit) {
        delay(30000L)
        timerFinished = true
    }

    if(timerFinished) {
        PreShared()
    }
}

如果您有任何类型的耗时后台任务,之后想要显示可组合项,则必须使用 ViewModel 类:

class SessionViewModel() : ViewModel() {

    var isWorkFinished by mutableStateOf(false)

    fun startBackgroundWork() {
        viewModelScope.launch(Dispatchers.IO) {
            // perform background task, calling suspend function...
            // afterwards, set this to true
            isWorkFinished = true

    }

}

现在您可以在 Composable 中使用 ViewModel,如下所示:

@Composable 
MainComposable(
    sessionViewModel: SessionViewModel = viewModel()
) {

    Button(onClick = { sessionViewModel.startBackgroundWork() }) {
        Text(text = "START")
    }

    if(sessionViewModel.isCountdownFinished) {
        PreShared()
    }

}

我希望这有帮助。如果是,您可以通过单击答案左侧的绿色复选标记来投票或接受此答案。

© www.soinside.com 2019 - 2024. All rights reserved.