如何运行 afterTextChanged 关闭主线程?

How to Run afterTextChanged off of the main thread?

@实体生物

我正在尝试更新数据库中的名称 属性。

@Entity(primaryKeys = ["name"])
data class Creature(
    @ColumnInfo(defaultValue = "New Creature") val name: String
)

@Dao CreatureDao

更新名称的查询在此处,在 DAO 中。

@Dao
interface CreatureDao {

    [...]

    // update creature name
    @Query("UPDATE Creature SET name=:newName WHERE name=:oldName")
    fun updateCreatureName(oldName: String, newName: String)
}

我的资料库

我的视图模型通过我的存储库进行查询

class MyRepository(private val creatureDao: CreatureDao) {

    [...]

    // update creature name
    @Suppress("RedundantSuspendModifier")
    @WorkerThread
    suspend fun updateCreatureName(oldName: String, newName: String) {
        creatureDao.updateCreatureName(oldName, newName)
    }
}

SharedViewModel

这是我的视图模型调用更新名称的地方属性

class SharedViewModel(
    private val repository: MyRepository
) : ViewModel() {

    [...]

    fun updateCreatureName(oldName: String, newName: String) {
        viewModelScope.launch { repository.updateCreatureName(oldName, newName) }
    }
}

关于片段

当 nameTextInputEditText 更改时,从 AboutFragment 调用此视图模型的 updateCreatureName() 方法...

class AboutFragment() : Fragment() {

    [...]

        // update creature record when creature name is edited
        binding.nameTextInputEditText.addTextChangedListener(object : TextWatcher {
            private lateinit var oldName: String
            private lateinit var newName: String

            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                oldName = s.toString()
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                newName = s.toString()
            }

            override fun afterTextChanged(s: Editable?) {
                sharedViewModel.updateCreatureName(oldName, newName)
            }

        })
    }
}

问题

我收到错误

java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

当我尝试启动 activity 片段时。我怎样才能运行

override fun afterTextChanged()

关闭主线程?

您可以使用 ExecutorService,然后调用传递 Runnable 的方法 submit()。在你 class 中创建一个实例,或者在你使用依赖注入的情况下注入一个单例。 也许 Jetpack 框架在这里也提供了一些更好的想法。

关键是使用

viewModelScope.launch(Dispatcher.IO){...}

而不是

viewModelScope.launch{...}

"When you don't pass a Dispatcher to launch, any coroutines launched from viewModelScope run in the main thread." source