我如何等到加载来自首选项数据存储的数据?
我正在尝试制作LibGDX实时墙纸。但是我认为这与我目前遇到的问题无关。基本上,我将墙纸的设置存储在首选项数据存储中。现在,如果您需要从数据存储中检索数据,则需要检索kotlin flow
并使用它来获取首选项。在libgdx的applicationListener
increate()方法中,我需要创建一个ktxscreen对象。我决定将所有偏好传递在我的屏幕
的构造函数中。但是,由于flow
的数据只能在coroutine中获得我的流
排放值。我用非常脏的解决了此问题,而(userPreferences == null)ume
一件代码,基本上会阻止整个应用程序,直到发出偏好,以便我可以构造我的ktxscreen
> 。解决这个问题的好方法是什么?
I'm trying to make a LibGDX Live Wallpaper. But I think that is unrelated to the problem I'm having at the moment. Basically, I'm storing the wallpaper's settings inside a Preferences DataStore. Now, if you need to retrieve data from the DataStore, you need to retrieve a Kotlin Flow
and use it to get the preferences. Inside LibGDX's ApplicationListener
inside the onCreate()
method, I need to create a KtxScreen object. I decided to pass all the preferences inside a constructor of my Screen
. However, since a Flow
's data can only be obtained inside a coroutine, I cannot construct my KtxScreen
object with the user preferences as a constructor parameter because I need to wait until my Flow
emits the values. I solved this with a very very dirty while (userPreferences == null) Unit
piece of code which basically blocks the whole app until the preferences are emitted so I can construct my KtxScreen
. What would be a good way to solve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在libgdx中可以接受以阻止渲染线程。这是与Android主线程的单独线程,因此它不会冻结Android UI,也不会使您有ANR的风险(应用程序不响应错误)。它会在阻塞时冻结任何游戏/壁纸渲染,但是当您仍在加载场景时,这还可以。
因此,在
中使用
或runblocking
create(create()render()
等待第一批设置。由于KTXSCREEN不使用create()
,因此您可以在属性初始化中直接阻止。您可以在流程上调用first()
从中获得一个项目,这对于您的KTXSCREEN类的初始设置就可以了。如果您使用的是libktx的
ktx-async
库,则可以在渲染线程上收集流程,因此,如果用户在运行壁纸时将用户更新设置,则将安全地更新您的设置。这是您如何实现这一目标的一个例子(我没有测试),但是可以处理许多可接受的不同方式。注意:这是假设您在渲染线程上实例化此屏幕,而不是Android主线程。渲染线程是用于调用
create()
的渲染线程,这是实例化第一个屏幕的典型场所。如果您想在墙纸中显示某种初始加载图像,则可以在
dender
函数中使用此类功能。但是我认为这不必是必要的,因为偏好可能会花费不到半秒钟的加载。It is acceptable in libGDX to block the rendering thread. This is a separate thread from the Android main thread, so it won't freeze the Android UI or put you at risk of an ANR (application not responding error). It will freeze any game/wallpaper rendering while blocking, but that's OK when you're still loading the scene.
So, it would be acceptable to use
runBlocking
increate()
orrender()
to wait for the first batch of settings. Since KtxScreen doesn't usecreate()
, you could block directly at the property initialization. You can callfirst()
on a Flow to get just one item from it, which would be fine for initial setup of your KtxScreen class.If you're using the
ktx-async
library from libKtx, you can collect your flow on the rendering thread, so then if the user updates the settings while your wallpaper is running, it will safely update your settings.Here's one example of how you might achieve this (I didn't test it), but there are many acceptable different ways it could be handled. Note: this is assuming you instantiate this screen on the rendering thread, not the Android main thread. The rendering thread is what is used to call
create()
on your game class, which is the typical place to instantiate your first screen.If you want to show some sort of initial loading image in your wallpaper, you could use if/else in your
render
function like this. But I don't think it should be necessary because preferences will take probably less than half a second to load.如果我们需要从数据存储中获取键值作为同步方式,那么我们需要使用Runblocking阻止线程,以便将数据返回原始数据类型中的数据。
INCASE以异步方式从数据存储中获取值,然后直接调用将返回流的方法。
If we need to fetch the key value from Datastore as synchronous way then we need to block the thread using runBlocking so that will return data in Primitive datatype.
Incase to fetch value from Datastore as Asynchronous way then directly call map method which will return Flow.