繁体   English   中英

如何等待 Preferences DataStore 中的数据加载完毕?

[英]How do I wait until data from Preferences DataStore is loaded?

我正在尝试制作 LibGDX 动态壁纸。 但我认为这与我目前遇到的问题无关。 基本上,我将墙纸的设置存储在 Preferences DataStore 中。 现在,如果您需要从 DataStore 检索数据,则需要检索 Kotlin Flow并使用它来获取首选项。 在 LibGDX 的ApplicationListeneronCreate()方法中,我需要创建一个 KtxScreen object。我决定将所有首选项传递到我的Screen的构造函数中。 但是,由于Flow的数据只能在协程内获取,因此我无法使用用户首选项作为构造函数参数来构造我的KtxScreen object,因为我需要等到我的Flow发出值。 我用一段非常非常脏的while (userPreferences == null) Unit代码解决了这个问题,它基本上阻止了整个应用程序,直到发出首选项,这样我才能构建我的KtxScreen 解决这个问题的好方法是什么?

在 libGDX 中阻塞渲染线程是可以接受的。 这是一个独立于 Android 主线程的线程,因此它不会冻结 Android UI 或让您面临 ANR(应用程序未响应错误)的风险。 它会在阻塞时冻结任何游戏/墙纸渲染,但是当您仍在加载场景时这没关系。

所以,在create()render()中使用runBlocking来等待第一批设置是可以接受的。 由于 KtxScreen 不使用create() ,您可以直接在属性初始化时阻塞。 您可以在 Flow 上调用first()以仅从中获取一个项目,这对于 KtxScreen class 的初始设置来说很好。

如果您使用的是 libKtx 中的ktx-async库,您可以在渲染线程上收集您的流程,这样如果用户在您的墙纸运行时更新设置,它会安全地更新您的设置。

这是您如何实现这一目标的一个示例(我没有测试它),但是有许多可接受的不同方式可以处理它。 注意:这是假设您在渲染线程而不是 Android 主线程上实例化此屏幕。 渲染线程用于在您的游戏 class 上调用create() ,这是实例化您的第一个屏幕的典型位置。

class MyScreen(
    val settingsFlow: Flow<UserPreferences>
): KtxScreen {

    var prefs: UserPreferences = runBlocking { settingsFlow.first() }

    init {
        settingsFlow
            .drop(1) // the first one should be the value we already got above
                     // unless the user changed them impossibly fast
            .onEach { prefs = it }
            .launchIn(KtxAsync)
    }

    //...
}

如果你想在你的壁纸中显示某种初始加载图像,你可以像这样在你的render function 中使用 if/else。 但我不认为这是必要的,因为偏好可能需要不到半秒的时间来加载。

class MyScreen(
    val settingsFlow: Flow<UserPreferences>
): KtxScreen {

    var _prefs: UserPreferences? = null

    init {
        settingsFlow
            .onEach { _prefs = it }
            .launchIn(KtxAsync)
    }

    override fun render() {
        val prefs = _prefs // for the sake of smart-casting
        if (prefs == null) {
            renderLoadingImage()
        } else {
            renderScene(prefs)
        }
    }

    //...

    private fun renderScene(prefs: UserPreferences) {
        //...
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM