簡體   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