You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开启飞行模式时Android App触发DeadObjectException崩溃求助

问题分析与解决方案

核心问题

开启飞行模式时,网络请求会抛出未捕获的IO异常,而viewModelScope中未处理的异常会直接导致应用崩溃。你看到的DeadObjectException是应用崩溃后系统层面的错误,并非真正的崩溃根源——真正的异常发生在repository.getAllCountries()调用时,因为没有捕获,协程直接终止并触发应用崩溃,导致后续日志无法打印。

修复代码

修改CountryListViewModel中的getAllCountries方法,添加异常捕获逻辑:

fun getAllCountries() {
    if (_countryList.value.isNotEmpty() || _loading.value) return

    viewModelScope.launch(Dispatchers.IO) {
        try {
            withContext(Dispatchers.Main) {
                _loading.value = true
            }
            val response = repository.getAllCountries()
            withContext(Dispatchers.Main) {
                if (response.isSuccessful) {
                    response.body()?.let { _countryList.value = it }
                } else {
                    onError("Error : ${response.message()} ")
                }
                _loading.value = false
            }
        } catch (e: Exception) {
            // 处理网络不可用、超时等异常
            withContext(Dispatchers.Main) {
                onError("网络连接失败: ${e.localizedMessage}")
            }
        }
    }
}

额外优化建议

  • 统一线程调度:把所有StateFlow的更新操作放到Dispatchers.Main中,避免线程切换混乱。
  • Repository层封装:建议让Repository的网络请求返回密封类,而非直接抛出异常,让ViewModel处理更清晰:
    // 示例密封类
    sealed class NetworkResult<out T> {
        data class Success<out T>(val data: T) : NetworkResult<T>()
        data class Error(val message: String) : NetworkResult<Nothing>()
    }
    
    // Repository中修改
    suspend fun getAllCountries(): NetworkResult<List<Country>> {
        return try {
            val response = apiService.getCountries()
            if (response.isSuccessful) {
                response.body()?.let { NetworkResult.Success(it) } ?: NetworkResult.Error("空响应")
            } else {
                NetworkResult.Error(response.message())
            }
        } catch (e: Exception) {
            NetworkResult.Error(e.localizedMessage ?: "未知错误")
        }
    }
    
    这样ViewModel中就无需额外try-catch,直接处理密封类结果即可。

关键说明

viewModelScope的特性是:如果协程中抛出未捕获的异常,会直接终止应用进程。所以所有可能抛出异常的挂起函数调用,都必须用try-catch包裹,或者在Repository层提前处理异常。

内容的提问来源于stack exchange,提问作者Hack123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 08:12:49