我正在使用一个房间数据库来运行一些繁重的数据库操作。我没有使用LiveData进行此操作,因为我只将结果用于计算。如果在我的主要片段中
override fun onActivityCreated(savedInstanceState: Bundle?) {
lifecycleScope.launch {
val result = viewModel.someHeavyOperation() // a suspend fun
doSomething(result)
}
}
我得到一个跳过xx帧!您的应用程序在启动时可能会在主线程上做很多工作。
如果忽略数据库查询,就不会得到这些工作。
这里的一些答案(比如这个或那个)似乎建议在IO线程上运行查询,比如
override fun onActivityCreated(savedInstanceState: Bundle?) {
lifecycleScope.launch {
withContext(Dispatchers.IO) {
val result = viewModel.someHeavyOperation() // a suspend fun
}
doSomething(result)
}
}
注意:Room使用自己的dispatcher在后台线程上运行查询。您的代码不应该使用withContext(Dispatchers.io)来调用挂起房间查询。这将使代码复杂化,并使您的查询运行得更慢。
然而,他们似乎只考虑了这样的情况,即昂贵的位是随后的计算,在那里他们似乎建议了类似于
override fun onActivityCreated(savedInstanceState: Bundle?) {
lifecycleScope.launch {
val result = viewModel.someOperation() // a suspend fun
withContext(Dispatchers.Default) {
doSomethingHeavy(result)
}
}
}
现在我的问题是:
如果room使用自定义调度器,那么从哪个调度器调用room查询有什么关系呢?
Room从2.1
版本开始引入了Kotlin Coroutine
支持。早些时候,他们不支持coroutine
。因此,首先,确保您的房间版本是否为build.gradle
文件中的2.1
或更高版本:
implementation "androidx.room:room-coroutines:${versions.room}"
如果您使用的room
版本早于2.1
,则room
将在调用方线程上执行操作。这意味着,如果我们在main
线程上给出Room的查询调用,它将在main
上执行操作。如果我们在io-background
线程上调用Room,它将在background
上执行。
如何在不阻塞主线程的情况下执行昂贵的房间查询?
为此,我们应该在io
线程上调用Room查询。你已经在做正确的事了
override fun onActivityCreated(savedInstanceState: Bundle?) {
lifecycleScope.launch {
withContext(Dispatchers.IO) {
val result = viewModel.someHeavyOperation() // a suspend fun
}
doSomething(result)
}
}
除此之外,如果需要添加等待直到房间查询调用返回,可以使用Async
启动器和Await()
方法
override fun onActivityCreated(savedInstanceState: Bundle?) {
lifecycleScope.launch {
val content = async(Dispatchers.IO) {
viewModel.someHeavyOperation() // a suspend fun
}
// Using below line, we are introducing waiting for completion of someHeavyOperation() on IO thread
// If we return any result from someHeavyOperation(), it can be accessed in result variable as below
var result = content.await()
}
}
}
参考:
我想为android构建一个计算器应用程序,为此我需要一个解析器来转换要求解的字符串表达式。现在Java和Kotlin不支持eval函数,仅仅为了一个操作而导入javascript引擎可能会让我面临各种漏洞。所以我做了自己的计算器解析器。现在它工作得很好,除了crash中的负数外,所有算术运算都工作得很好。我确实知道问题是什么,因为我使用数学符号分隔字符串,但我不能在负值中执行任何操作。 输入:-
null 我看到过其他答案,提到了一个名为UCANAccess的Access数据库的JDBC驱动程序。如何设置Java项目以使用这种方法? (建议从Java使用Access数据库的更好方法的答案也是最受欢迎的。)
问题内容: 我有一个使用JAXB创建的相当大的重复XML。将整个对象存储在内存中然后进行封送处理会占用太多内存。本质上,我的XML如下所示: 目前,我对这个问题的解决方案是将根标记“硬编码”到输出流,并逐个编组每个重复元素: JAXB以某种方式生成这样的XML 尽管这是一个有效的XML,但它看起来很难看,所以我想知道是否有任何方法告诉编组不要为item元素放置名称空间?还是有更好的方法使用JAXB
问题内容: 我想在Centos7上使用shell脚本自动生成一对ssh密钥,我已经尝试过 所有这些命令都不起作用,仅输入一个“ enter”,然后在“ Enter passphrase(空无密码)为空”时停止shell脚本,我只想知道如何在shell中连续模拟多个“ enter”。 非常感谢任何人的帮助! 问题答案: 只需 使用一个空白通 使用标志: 要覆盖密钥文件 (在此示例中): 从 手册 页
我有一个动作执行,其中一个if/fe是如果用户按“A”键,它会将文本设置为不同的内容。程序不是在按“A”后设置文本,而是跳过设置文本并向下移动到下面的if语句。我的问题是,如何让我的程序在我的if语句之前设置文本?我的代码在下面,谢谢!
RT,大表,随时都有数据的读写