Сопрограмма пропускается при запуске фонового потока - PullRequest
1 голос
/ 03 августа 2020

Итак, я столкнулся со странной проблемой в моем коде, когда сопрограмма полностью пропускается, когда я отлаживаю свой код, и я не уверен, почему это происходит.

Обычно я вызываю этот метод (insertLabelBind) в моем фрагменте в onViewCreated.

//FRAGMENT
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val addLabelButton: ImageView = view.findViewById(R.id.profile_edit_add_label_row_button)
        val addQuestionButton: ImageView = view.findViewById(R.id.profile_edit_add_question_response_button)
        val editBookImage: ImageView = view.findViewById(R.id.profile_image_edit)
        navController = Navigation.findNavController(view)
        bindBasicInfo(view)
        bindLabels(view)
        bindQandA(view)
        addLabelButton.setOnClickListener{
                insertLabelBind(view)

            //add to label live data

        }}

     private fun insertLabelBind(view: View) = launch{
        val word: EditText? = view.findViewById(R.id.profile_label_edit_add_row)
        val labelTag = viewModel.createLabel(word?.text.toString())
        labelTag?.observeOnce(viewLifecycleOwner, Observer { tag ->
            if (tag == null) return@Observer
            CoroutineScope(Main).launch {
                setLabelTextInUI(tag, word)
            }
        })
    }

Затем во ViewModel фрагмента это вызывается, и ему не удается получить результат метки

//VIEWMODEL
suspend fun createLabel(label: String): LiveData<LabelTag>? {
            var labelResult: LiveData<LabelTag>? = null
            var userLabelResult: LiveData<UserLabel>? = null

            val labelTag = LabelTag(
                0,
                profileId,
                label,
                LocalDateTime.now().toString(),
                LocalDateTime.now().toString(),
                ""
            )

            labelResult = coverRepository.createLabelTag(labelTag)
            userLabelResult = coverRepository.getSingleUserLabel(profileId, labelResult?.value!!.id)

            if (userLabelResult == null) {
                val userLabel = UserLabel(
                    0,
                    profileId,
                    labelResult!!.value!!.id,
                    1,
                    label,
                    LocalDateTime.now().toString(),
                    LocalDateTime.now().toString(),
                    ""
                )
                userLabelResult = coverRepository.createUserLabel(userLabel)
            }
        return if (userLabelResult != null) {
            labelResult
        } else
            null
    }

В репозитории этот метод createLabelTag вызывается

//REPOSITORY
    override suspend fun createLabelTag(labelTag: LabelTag): LiveData<LabelTag>? {
        return withContext(IO) {
            val result = createLabelTagSource(labelTag)
            when (result.status) {
                Status.SUCCESS -> labelTagDao.getTagById(labelTag.id)
                Status.LOADING -> null
                Status.ERROR -> null
            }
        }

    }

    private suspend fun createLabelTagSource(labelTag: LabelTag): Resource<LabelTag> {
        return labelTagDataSource.createLabelTag(
            labelTag
        )
    }

Затем вызывается labelTagDataSource

//DATASOURCE
    override suspend fun createLabelTag(labelTag: LabelTag): Resource<LabelTag> {
        return try {
            val fetchedLabelTag = responseHandler.handleSuccess(coverApiService
                .createLabelTag(labelTag))
            val list = listOf(fetchedLabelTag.data!!)
            list.first().profileId = labelTag.profileId
            _downloadedLabelTag.postValue(list)
            fetchedLabelTag
        } catch (e: NoConnectivityException) {
            Log.e("Connectivity", "No internet connection.", e)
            responseHandler.handleException(e)
        } catch (e: Exception) {
            responseHandler.handleException(e)
        }
    }

Источник данных запускает наблюдатель в репозитории для downloadLabelTag, и данные сохраняются в DB комнаты labelTag

//REPOSITORY
     labelTagDataSource.apply {
            downloadedLabelTag.observeForever { newLabelTag ->
                persistFetchedLabelTag(newLabelTag)
            }
        }

    private fun persistFetchedLabelTag(labelTags: List<LabelTag>) {
        job = Job()
        job?.let { repoJob ->
            CoroutineScope(IO + repoJob).launch {
                if(labelTags.size > 1)
                    labelTagDao.deleteAll()
                for(result in labelTags){
                    labelTagDao.upsertTag(result)
                }
                repoJob.complete()
            }
        }
    }
//DAO
interface LabelTagDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun upsertTag(label: LabelTag)

    @Query("SELECT * FROM label_tag WHERE label = :tag")
    fun getLabelByTag(tag: String): LiveData<LabelTag>

    @Query("SELECT * FROM label_tag WHERE id = :id")
    fun getTagById(id: Long): LiveData<LabelTag>

    @Query("SELECT * FROM label_tag WHERE profileId = :profileId")
    fun getTagMultipleTags(profileId: Int): LiveData<List<LabelTag>>

    @Query("DELETE FROM label_tag")
    suspend fun deleteAll()
}

Проблема возникает из-за Repository.persistFetchedLabelTag, и CoroutineScope полностью пропускается. В результате labelResult ViewModel возвращает значение null. Хотелось бы знать, почему эта сопрограмма пропускается. Любая помощь будет благодарна.

...