Kle*_*kus 5 mobile android kotlin android-room android-jetpack
好的,所以,我正在尝试使用 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"
Run Code Online (Sandbox Code Playgroud)
这是道代码:
@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)
}
Run Code Online (Sandbox Code Playgroud)
数据库位:
@Database(entities = arrayOf(Debts::class), version = 1)
abstract class AppDatabase : RoomDatabase()
{
abstract fun debtsDao() : DebtsDao
}
Run Code Online (Sandbox Code Playgroud)
这是我使用它的功能:
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)
}
Run Code Online (Sandbox Code Playgroud)
我尝试按照 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)
Run Code Online (Sandbox Code Playgroud)
这应该是问题的根源:无法访问主线程上的数据库,因为它可能会长时间锁定 UI。
我在这里缺少什么?提前致谢!!
Vir*_*hit 10
房间数据库不希望用户在主线程上执行操作。
\n\n您应该使用后台线程来执行任务。
\n\n您可以使用
\n\n.allowMainThreadQueries()\n
Run Code Online (Sandbox Code Playgroud)\n\n跳过建议的解决方案,但建议使用线程来执行任务。
\n\n以下是一些选项。
\n\n1)
\n\nAsyncTask.execute(() -> //Write your db code here);
2)
\n\n Thread {\n //Do your database\xc2\xb4s operations here\n }.start()\n
Run Code Online (Sandbox Code Playgroud)\n
Room 阻止您从 UI 线程使用它,因为数据库查询将访问磁盘,这可能需要很长时间,并且在此期间阻塞 UI 线程将冻结用户界面。你应该从后台线程调用 Room,你如何到达那里取决于你。您可以选择 Java 线程原语、Executors、RxJava、协程等,具体取决于您熟悉的内容。
从技术上讲,您可以通过使用 来规避 Room 的这种限制allowMainThreadQueries
,但出于上述原因,您永远不应在实际应用程序中这样做。此开关仅用于测试。
您还可以查看到返回LiveData
,Flowable
或相似类型这是从本质室异步,因为在这些情况下,你可以调用从UI线程间的方法。
有关更多信息,请参阅Room 文档。
归档时间: |
|
查看次数: |
11888 次 |
最近记录: |