问题
My Coroutine is running on the main thread, which i've specified in my Coroutine context:
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)
}
}
}
But I'm still getting this error:
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
on my above Coroutine call CustomApplication.database?.clearAllTables()
to my Room
database.
Here is my 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()
}
Why am I still getting the error if my coroutine context runs on the main thread?
回答1:
The error says that it should NOT run on the main thread. Database operations (and every other form of IO) can take a long time and should be run in the background.
You should use Dispatchers.IO
which is designed for running IO operations.
回答2:
You can't use Dispatchers.Main
for the long-running task. You have to use Dispatchers.IO
for database operations, look likes:
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)
}
}
}
来源:https://stackoverflow.com/questions/57657741/cannot-access-database-on-the-main-thread-since-it-may-potentially-lock-the-ui