我的协程正在主线程上运行,这是我在协程上下文中指定的:
class ClickPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs), CoroutineScope, View.OnClickListener {
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main
override fun onClick(v: View?) {
when (key){
"logout" -> {
CoroutineScope(coroutineContext).launch {
CustomApplication.database?.clearAllTables()
Log.d("MapFragment", "Cleared Tables")
}
if (Profile.getCurrentProfile() != null) LoginManager.getInstance().logOut()
FirebaseAuth.getInstance().signOut()
val intent = Intent(context, MainActivity::class.java)
context.startActivity(intent)
}
}
}
但是我仍然收到此错误:
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
在我上面的协程调用CustomApplication.database?.clearAllTables()
到我的Room
数据库中。
这是我的CustomApplication
:
class CustomApplication : Application() {
companion object {
var database: AppDatabase? = null
}
override fun onCreate() {
super.onCreate()
CustomApplication.database = Room.databaseBuilder(this, AppDatabase::class.java, "AppDatabase").build()
}
如果我的协程上下文在主线程上运行,为什么仍会出现错误?
答案 0 :(得分:6)
该错误表明不应在主线程上运行。数据库操作(以及其他所有形式的IO)可能会花费很长时间,因此应在后台运行。
您应使用专门用于运行IO操作的Dispatchers.IO
。
答案 1 :(得分:1)
您不能将Dispatchers.Main
用于长时间运行的任务。您必须使用Dispatchers.IO
进行数据库操作,如下所示:
class ClickPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs), CoroutineScope, View.OnClickListener {
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO
override fun onClick(v: View?) {
when (key){
"logout" -> {
CoroutineScope(coroutineContext).launch {
CustomApplication.database?.clearAllTables()
Log.d("MapFragment", "Cleared Tables")
if (Profile.getCurrentProfile() != null) LoginManager.getInstance().logOut()
FirebaseAuth.getInstance().signOut()
}
val intent = Intent(context, MainActivity::class.java)
context.startActivity(intent)
}
}
}
答案 2 :(得分:-2)
您好,这个问题是因为数据库必须运行在主线程上。 因此,您必须将这行代码添加到数据库中 部分
Room.databaseBuilder(context.getApplicationContext(),
DataBaseTextChat.class, Constants.DB_TEXT_CHAT)
.allowMainThreadQueries()
.addCallback(roomCallBack).build();