Kotlin coroutineScope + комната: изменить действие меню панели инструментов с сопрограммы - PullRequest
0 голосов
/ 12 апреля 2020

Есть большие проблемы.

Иногда при изменении действий меню из сопрограммы происходит сбой приложения.

Я не понимаю, почему. Спасибо!

ShowActivitySimple:

class ShowActivitySimple : AppCompatActivity() {

    private val completableJob = Job()
    private val coroutineScope = CoroutineScope(Dispatchers.IO + completableJob)

    ...

    override fun onDestroy() {
        super.onDestroy()
        completableJob.cancel()
        saveSettings()
    }

    override fun onPrepareOptionsMenu(menu: Menu): Boolean {

        coroutineScope.launch(Dispatchers.IO) {
            if (db.bookmarkDao().newsIsBookmarked(news_id) > 0) {

                runOnUiThread {
                    menu.findItem(R.id.action_add_bookmark).isVisible = false
                    menu.findItem(R.id.action_remove_bookmark).isVisible = true
                }

            } else {
                runOnUiThread {
                    menu.findItem(R.id.action_add_bookmark).isVisible = true
                    menu.findItem(R.id.action_remove_bookmark).isVisible = false
                }
            }
        }

        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {

        val id = item.itemId

        when (item.itemId) {

            R.id.action_add_bookmark -> {
                coroutineScope.launch(Dispatchers.IO){
                    db.bookmarkDao().insertBookmark(Bookmark(null, news_id, page_title, created, 0))
                    runOnUiThread {
                        invalidateOptionsMenu()
                    }
                }
                return true
            }
            R.id.action_remove_bookmark -> {
                coroutineScope.launch(Dispatchers.IO) {
                    db.bookmarkDao().deleteByNewsId(news_id)
                    runOnUiThread {
                        invalidateOptionsMenu()
                    }
                }
                return true
            }


        }

        return super.onOptionsItemSelected(item)
    }

База данных приложений:

@Database(entities = [Bookmark::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
    abstract fun bookmarkDao(): BookmarkDao

    companion object {
        var INSTANCE: AppDatabase? = null

        fun getAppDataBase(context: Context): AppDatabase? {
            if (INSTANCE == null){
                synchronized(AppDatabase::class){
                    INSTANCE = Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, "bookmarks.db").build()
                }
            }
            return INSTANCE
        }

        fun destroyDataBase(){
            INSTANCE = null
        }
    }
}

Журнал ошибок:

android .view.ViewRootImpl $ CalledFromWrongThreadException: только исходный поток, создавший иерархию представлений, может касаться его представлений. в android .view.ViewRootImpl.checkThread (ViewRootImpl. java: 6956) в android .view.ViewRootImpl.invalidateChildInParent (ViewRootImpl. java: 1119) в android .view.ViewGroup.invalidCate . java: 5244) в android .view.View.invalidateInternal (просмотр. java: 13596) в android .view.View.invalidate (просмотр. java: 13560) в android. view.View.invalidate (View. java: 13544) в android .widget.TextView.setCompoundDrawables (TextView. java: 2289) в androidx.appcompat.widget.AppCompatTextView.setCompoundDrawables (AppCompatTextView * * 10 *. 560) в androidx.appcompat.view.menu.ActionMenuItemView.setIcon (ActionMenuItemView. java: 231) в androidx.appcompat.view.menu.ActionMenuItemView.initialize (ActionMenuItemView. java: 126) в androidxid.compat. .ActionMenuPresenter. : 193) в droidx.appcompat.view.menu.BaseMenuPresenter.updateMenuView (BaseMenuPresenter. java: 105) в androidx.appcompat.widget.ActionMenuPresenter.updateMenuView (ActionMenuPresenter. java: 226.u.u.enu.Udu.Un.U.U.U.U. dispatchPresenterUpdate (MenuBuilder. java: 292) в androidx.appcompat.view.menu.MenuBuilder.onItemsChanged (MenuBuilder. java: 1063) в androidx.appcompat.view.menu.MenuBuilder.onhedis. 1102) на androidx.appcompat.view.menu.MenuItemImpl.setVisible (MenuItemImpl. java: 665) на com.cis.committee.news.ShowActivitySimple $ onPrepareOptionsMenu $ 1.invokeSuspend (ShowActivitySimple.kt: 3847 в: 389) coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt: 33) в kotlinx.coroutines.DispatchedTask.run (Dispatched.kt: 241) в kotlinx.coroutines.scheduling. .coroutines.scheduling.CoroutineScheduler.access $ runSafely (CoroutineScheduler.kt: 60) в kotlinx.coroutines.sc heduling.CoroutineScheduler $ Worker.run (CoroutineScheduler.kt: 740)

Строка ошибки 389 - onPrepareOptionsMenu

...