0

我收到“无法访问主线程上的数据库,因为它可能会长时间锁定 UI。” 错误,但据我了解,我正在启动一个新的协程将数据插入数据库。我究竟做错了什么?

放射性:

        val finishButton : Button = findViewById(R.id.radioFinishButton)
        finishButton.setOnClickListener {
            val radioName = findViewById<EditText>(R.id.radioName)
            val radioUri = findViewById<EditText>(R.id.radioUri)
            val replyIntent = Intent()

            when {
                TextUtils.isEmpty(radioName.text) -> radioName.error = "Radio name is required!"
                TextUtils.isEmpty(radioUri.text) -> radioUri.error = "Radio URL is required!"
                else -> {
                    replyIntent.putExtra(EXTRA_REPLY_NAME, radioName.text.toString())
                    replyIntent.putExtra(EXTRA_REPLY_URI, radioUri.text.toString())
                    setResult(Activity.RESULT_OK, replyIntent)
                    finish()
                }
            }
        }

无线电片段:

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val getResult = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ){
            var name = ""
            var uri = ""
            if(it.resultCode == Activity.RESULT_OK){
                it.data?.getStringExtra(RadioActivity.EXTRA_REPLY_NAME)?.let{ reply ->
                    name = reply
                }
                it.data?.getStringExtra(RadioActivity.EXTRA_REPLY_URI)?.let{ reply ->
                    uri = reply
                }
                Toast.makeText(context, "Name = ${name}, uri = ${uri}", Toast.LENGTH_LONG).show()
                val radio = Radio(5, name, uri)
                radioViewModel.insert(radio)
            }else{
                Toast.makeText(context, "Error while saving", Toast.LENGTH_LONG).show()
            }
        }

        val recyclerView = view.findViewById<RecyclerView>(R.id.radioRecyclerView)
        val adapter = RadioListAdapter()
        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(context)

        radioViewModel.radioList.observe(viewLifecycleOwner) {
            it.let{
                adapter.submitList(it)
            }
        }
    }

无线电存储库:

val radioList: Flow<List<Radio>> = radioDao.getAll()
    @Suppress("RedundantSuspendModifier")
    @WorkerThread
    suspend fun insert(radio: Radio) {
        radioDao.insert(radio)
    }

收音机型号:

    fun insert(radio: Radio) = viewModelScope.launch {
        repository.insert(radio)
    }
4

2 回答 2

0

尝试在您的 viewmodelScope 上指定调度程序

fun insert(radio: Radio) = viewModelScope.launch(Dispatchers.IO) {
    repository.insert(radio)
}

如果它不起作用,请尝试使用切换上下文withContext

fun insert(radio: Radio) = viewModelScope.launch {
    withContext(Dispatchers.IO) {
        repository.insert(radio)
    }
}
于 2022-01-11T21:02:21.417 回答
0

尝试在以下位置切换上下文RadioRepository

suspend fun insert(radio: Radio) = withContext(Dispatchers.IO) {
    radioDao.insert(radio)
}

您正在使用@Suppress("RedundantSuspendModifier")注释,它会抑制RedundantSuspendModifier错误。此错误意味着您的insert函数是非函数,suspend并且将在调用它的线程中运行。

withContext(Dispatchers.IO)切换协程的上下文,使insert函数在后台(工作)线程中运行。

于 2022-01-11T20:55:43.447 回答