开发者社区> 问答> 正文

错误:无法访问主线程上的数据库,因为它可能长时间锁定UI。-使用Kotlin的Android Roo

好的,因此,我正在尝试使用Android Room为该项目创建此数据库。

首先,这是我在Gradle文件中关于此问题的内容:


//Room database
    implementation "androidx.lifecycle:lifecycle-viewmodel:2.1.0"

    implementation "androidx.room:room-runtime:2.2.3"
    kapt "androidx.room:room-compiler:2.2.3"
    implementation "androidx.room:room-ktx:2.2.3"

这是Dao代码:

@Dao
interface DebtsDao {

    @Query("SELECT * FROM debts")
    fun getDebtsList() : List<Debts>

    @Query("SELECT * FROM debts WHERE name LIKE :name")
    fun getNamedDebt(name : String) : Debts

    @Insert
    fun insertInDatabase(debt : Debts)

    @Delete
    fun deleteFromDatabase(debt : Debts)

}

数据库位:

@Database(entities = arrayOf(Debts::class), version = 1)
abstract class AppDatabase : RoomDatabase()
{
    abstract fun debtsDao() : DebtsDao
}

这是我使用它的功能:

    fun refreshRecyclerView()
    {
        val database = Room.databaseBuilder(applicationContext, AppDatabase::class.java, "account").build()

        val list : List<Debts> = database.debtsDao().getDebtsList()

        recycler_view_debts.layoutManager = LinearLayoutManager(this)
        recycler_view_debts.adapter = RecAdapter(this, list)
    }

我尝试按照Android页面上的教程进行操作,但未按计划进行。我在Android Studio上收到以下错误:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.project.watchingmoneyfly, PID: 17067
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.project.watchingmoneyfly/com.project.watchingmoneyfly.Activities.MainActivity}: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
     Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
        at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:267)
        at androidx.room.RoomDatabase.beginTransaction(RoomDatabase.java:351)
        at com.project.watchingmoneyfly.RoomDatabase.DebtsDao_Impl.insertInDatabase(DebtsDao_Impl.java:79)
        at com.project.watchingmoneyfly.Activities.MainActivity.onCreate(MainActivity.kt:25)
        at android.app.Activity.performCreate(Activity.java:6662)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6077) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 

这应该是问题的根源:无法访问主线程上的数据库,因为它可能长时间锁定UI。

我在这里想念什么?提前致谢!!

展开
收起
Puppet 2020-01-06 14:25:09 2261 0
1 条回答
写回答
取消 提交回答
  • Room阻止您从UI线程使用它,因为数据库查询将访问磁盘,这可能需要很长时间,并且在该持续时间内阻止UI线程将冻结用户界面。您应该从后台线程调用Room,而如何到达则取决于您自己。您可以选择Java线程原语,执行程序,RxJava,协程等,具体取决于您熟悉的内容。

    您可以通过使用技术上规避间的这种限制allowMainThreadQueries,但你应该从来没有这样做在实际应用中,由于上述原因奠定了。该开关仅用于测试。

    您还可以查看到返回LiveData,Flowable或相似类型这是从本质室异步,因为在这些情况下,你可以调用从UI线程间的方法。

    有关更多信息,请参见会议室文档。

    2020-01-06 14:25:26
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
58同城Android客户端Walle框架演进与实践之路 立即下载
Android组件化实现 立即下载
蚂蚁聚宝Android秒级编译——Freeline 立即下载