Итак, я столкнулся со странной проблемой в моем коде, когда сопрограмма полностью пропускается, когда я отлаживаю свой код, и я не уверен, почему это происходит.
Обычно я вызываю этот метод (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. Хотелось бы знать, почему эта сопрограмма пропускается. Любая помощь будет благодарна.