Kotlin和Retrofit:HTTP失败:java.io.IOException:仅在片段中取消

gxwragnw  于 2023-05-18  发布在  Kotlin
关注(0)|答案(1)|浏览(339)

我不明白为什么当我从一个Fragment调用时它会抛出这个错误。如果我从MainActivity调用,代码就可以工作。
下面是ViewModel中的代码:

fun initialSync(syncRequest: SyncRequest) {
    _uiState.value = SyncUiState.Loading
    viewModelScope.launch(coroutineDispatcherProvider.IO()) {
        try {
            val result = getSyncUseCase.execute(syncRequest)
            _uiState.value = SyncUiState.Loaded(SyncItemUiState(result))
        } catch (error: Exception) {
            _uiState.value = SyncUiState.Error(error.message.toString())
        }
    }
}

在用例中,我称之为Repository实现:

override suspend fun getSync(syncRequest: SyncRequest): SyncResponse {
    var syncResponse = SyncResponse(SpannableStringBuilder(), emptyList())
    if(syncRequest.type==1) {
        val syncNetwork = syncFactory.create(Source.NETWORK).getSync(syncRequest)
        if(syncNetwork.allToday.isNotEmpty()) {
            syncResponse.allToday=syncNetwork.allToday
            syncResponse.dataForView=syncNetwork.dataForView
        }else{
            val syncFirebase = syncFactory.create(Source.FIREBASE).getSync(syncRequest)
            syncResponse.allToday=syncFirebase.allToday
            syncResponse.dataForView=syncFirebase.dataForView
        }
    }
    return syncResponse
}

下面是管理API调用的代码:

override suspend fun getSync(syncRequest: SyncRequest): SyncResponse {
    val todayAll=todayApi.getTodayAll("all")
    val syncResponse= SyncResponse(SpannableStringBuilder(),todayAll)
    return syncResponse
}

下面是API调用的代码:

@GET("today/{thePath}")
suspend fun getTodayAll(@Path("thePath") thePath: String?): List<Today?>

ViewModel捕获此错误:
kotlinx.coroutines.JobCancellationException:作业已取消; job=SupervisorJobImpl{取消}@c05b47
我不明白为什么当我从一个Fragment调用时会出现这个错误:

val syncRequest = SyncRequest(0, 1,false,false)
syncViewModel.initialSync(syncRequest)

同样的调用在MainActivity中也能正常工作。我在模拟器里测试代码。在Fragment中,当用户单击按钮时调用代码。

mwkjh3gx

mwkjh3gx1#

我通过调用lifecycleScope.launch内部的ViewModel来实现它:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return activity?.let {
        val builder = AlertDialog.Builder(it)
        val ssb = SpannableStringBuilder()
        val intro = String.format(
            "%s %s%n%s",
            requireActivity().resources.getString(R.string.accept_intro),
            requireActivity().resources.getString(R.string.privacy),
            requireActivity().resources.getString(R.string.terms)
        )
        builder.setMessage(ssb)
            .setPositiveButton(requireActivity().resources.getString(R.string.ok)) { _, _ ->
                val syncRequest = SyncRequest(0, 1, isNightMode = false, isVoiceOn = false)
                lifecycleScope.launch(Dispatchers.IO) {
                    syncViewModel.initialSync(syncRequest)
                }
            }
            .setNegativeButton(requireActivity().resources.getString(R.string.cancel)) { _, _ ->
                // User cancelled the dialog
            }
            .apply {
                this@AcceptanceFragmentDialog.isCancelable = true
                setCancelable(true)
            }
        builder.create()
    } ?: throw IllegalStateException("Activity cannot be null")
}

相关问题