运行后台线程时协程被跳过

时间:2020-08-03 16:23:10

标签: android kotlin kotlin-coroutines coroutine coroutinescope

所以我在代码中遇到一个奇怪的问题,当我调试代码时,协程被完全跳过了,我不确定为什么会这样。

基本上,我在onViewCreated的Fragment中调用此方法(insertLabelBind)。

//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)
            }
        })
    }

然后在Fragment的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观察者,数据被持久保存到labelTag室DB

//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已被完全跳过。这导致ViewModel的labelResult返回null。想知道为什么协程被跳过了。任何帮助将不胜感激。

0 个答案:

没有答案