所以我在代码中遇到一个奇怪的问题,当我调试代码时,协程被完全跳过了,我不确定为什么会这样。
基本上,我在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。想知道为什么协程被跳过了。任何帮助将不胜感激。