從視圖中插入帶有空間的數據:無法訪問主線程上的數據庫

布克斯

我是 kotlin 和 android 開發的初學者。在 Room教程中遵循了Persist data並且我有一個流行的問題來保存我的數據:

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

我通過閱讀其他回復來理解原因。但我不明白如何處理它。

我的實體及其 DAO :

@Entity
data class AccountConfiguration(
    @PrimaryKey val server_address: String,
    @ColumnInfo(name = "user_name") val user_name: String,
    @ColumnInfo(name = "password") val password: String,  // FIXME : secure storage
    @ColumnInfo(name = "notify_hungry") val notify_hungry: Boolean,
    @ColumnInfo(name = "notify_thirsty") val notify_thirsty: Boolean,
    @ColumnInfo(name = "notify_ap") val notify_ap: Boolean,
    @ColumnInfo(name = "network_grab_each") val network_grab_each: Int,
)

@Dao
interface AccountConfigurationDao {
    @Query("SELECT * FROM accountconfiguration LIMIT 1")
    fun get(): Flow<AccountConfiguration>

    @Query("DELETE FROM accountconfiguration")
    fun clear()

    @Insert
    fun insert(account_configuration: AccountConfiguration)
}

它的視圖模型:


class AccountConfigurationViewModel(private val repository: AccountConfigurationRepository) : ViewModel() {

    val accountConfiguration: LiveData<AccountConfiguration> = repository.accountConfiguration.asLiveData()

    fun insert(account_configuration: AccountConfiguration) = viewModelScope.launch {
        repository.update(account_configuration)
    }

    fun isEntryValid(server_address: String, user_name: String, password: String, network_grab_each: Int): Boolean {
        if (server_address.isBlank() || user_name.isBlank() || password.isBlank() || network_grab_each < 5 * 60) {
            return false
        }
        return true
    }

}

數據庫應用

然後,有關視圖的一部分(此處為整個文件):

class AccountConfigurationFragment : Fragment() {

    private var _binding: AccountConfigurationFragmentBinding? = null

    // This property is only valid between onCreateView and
    // onDestroyView.
    private val binding get() = _binding!!

    private val viewModel: AccountConfigurationViewModel by activityViewModels {
        AccountConfigurationViewModelFactory(
            (activity?.application as RollingDashboardApplication).account_configuration_repository
        )
    }
    lateinit var accountConfiguration: AccountConfiguration

    // [...] hidden code

    private fun save() {
        Toast.makeText(context, R.string.saving, Toast.LENGTH_LONG).show()
        if (isEntryValid()) {
            val networkGrabEach = 3600 // FIXME : determine value for real

            viewModel.insert(
                AccountConfiguration(
                    server_address = binding.textInputServerAddress.text.toString(),
                    // [...] hidden code
                    network_grab_each = networkGrabEach,
                )
            )
            Toast.makeText(context, R.string.account_configuration_saved, Toast.LENGTH_LONG).show()
            findNavController().navigate(R.id.action_AccountConfigurationFragment_to_DashboardFragment)
        } else {
            Toast.makeText(context, R.string.wrong_inputs, Toast.LENGTH_LONG).show()
        }

    }

    // [...] hidden code
}

我不明白這個調用viewModel.insert(如何異步的。NoteAccountConfigurationRepository.update已經是一個suspend函數。我嘗試通過這樣的修改沒有成功(同樣的錯誤):

-    fun insert(account_configuration: AccountConfiguration) = viewModelScope.launch {
+    suspend fun insert(account_configuration: AccountConfiguration) = viewModelScope.launch {
            lifecycleScope.launch { // coroutine on Main
                viewModel.insert(
                    // ...

我怎樣才能讓這個數據庫插入非阻塞 UI?

普拉文

你必須讓你的DAO方法掛起,這樣它們就不會阻塞UI thread

@Dao
interface AccountConfigurationDao {
    @Query("SELECT * FROM accountconfiguration LIMIT 1")
    fun get(): Flow<AccountConfiguration>

    @Query("DELETE FROM accountconfiguration")
    suspend fun clear() //make this suspend

    @Insert
    suspend fun insert(account_configuration: AccountConfiguration) //make this suspend
}

我試過你的github代碼,你必須取消註釋implementation "androidx.room:room-runtime:$room_version"

我認為 Room 中存在一個錯誤,2.3.0因為它Not sure how to handle query method's return type (java.lang.Object).在將suspend關鍵字添加DAO. 你應該使用房間2.4.0-beta02

def room_version = "2.4.0-beta02"
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何從 C# 中的 SQL Server 數據庫填充數據網格視圖

無法使用 PHP 訪問 JSON 數據

如何將數據從 expessjs 中間件傳遞到視圖,

Quest DB 無法使用帶有線路協議的 Java 運行教程數據插入

在數據庫和實體列中添加類型轉換器後,無法在房間數據庫中保存整數列表

無法訪問 Node JS 中的請求數據

無法將 POST 變量插入數據庫

從 React 訪問實時數據庫列表

無法訪問 FETCH 響應數據

有沒有辦法在 Snowflake 中的所有數據庫和模式中創建可訪問的屏蔽策略?

無法將數據發送到 Django 中的數據庫

無法更新實時數據庫中的數據

不要在數據庫mysql中插入數據

無法將選中的值插入數據庫

無法在 mysql 數據庫中插入數據:'ValueError:無法處理參數'

帶有預填充數據庫的房間

如何使用地圖將數據插入到我的 Firebase 數據庫中?

我想通過 RMI 從數據庫中獲取完整的數據。我使用了數組方法。我無法成功編寫代碼

濃縮咖啡測試“無法訪問主線程上的數據庫”時出現房間數據庫錯誤

使用 Laravel 中的控制器將數據從數據庫傳遞到刀片視圖

MongoDB 是否有數據庫訪問限制?

如何從 SQL 數據庫編輯網格視圖中顯示的數據

從 Django 中的第二個外部 SQLite 數據庫訪問數據

我無法將數據從控制器傳遞到 CodeIgniter 3 中的視圖

vue 3 無法訪問方法中的數據對象

其他數據不會被推送到數據庫中,只有圖像

無法從 foreach 循環內的數組訪問數據 - Codeigniter

無法使用 Laravel 和 React 在 MySql 數據庫中存儲數據

從獲取響應中訪問數據