用于调用 REST API 的协程 - > 致命异常:main



我需要从 REST API 获取一些数据,当我连接 4G 或 wifi 时一切正常,但是当我处于飞行模式时,应用程序崩溃并显示:"E/Android运行时:致命异常:主要"

在此之前,我有一个日志(不是错误说:"跳过了 1013 帧! 应用程序可能在其主线程上做了太多工作。

所以我想在没有网络的情况下获取 API 会使应用程序崩溃,因为它在主线程中运行。但是我正在使用协程,对我来说,我做对了:

视图模型

private val viewModelJob = SupervisorJob()
private val viewModelScope = CoroutineScope(viewModelJob + Dispatchers.Main)
init {
viewModelScope.launch {
videosRepository.refreshVideos()
}
}

存储 库

suspend fun refreshVideos() {
withContext(Dispatchers.IO) {
val playlist = Network.devbytes.getPlaylist().await()
//database.videoDao().insertAll(*playlist.asDatabaseModel())
}
}

服务

/**
* A retrofit service to fetch a devbyte playlist.
*/
interface DevbyteService {
@GET("devbytes.json")
fun getPlaylist(): Deferred<NetworkVideoContainer>
}
/**
* Build the Moshi object that Retrofit will be using, making sure to add the Kotlin adapter for
* full Kotlin compatibility.
*/
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
/**
* Main entry point for network access. Call like `Network.devbytes.getPlaylist()`
*/
object Network {
// Configure retrofit to parse JSON and use coroutines
private val retrofit = Retrofit.Builder()
.baseUrl("https://devbytes.udacity.com/")
.addConverterFactory(MoshiConverterFactory.create(moshi))
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.build()
val devbytes: DevbyteService = retrofit.create(DevbyteService::class.java)
}

所以完整的链是:

ViewModel -> 与 Dispatchers.Main 的协程

调用存储库 -> 挂起函数,该函数启动与 Dispatchers.IO 的协程

通过对象网络调用服务 ->,我得到一个带有返回延迟的 getPlaylist(( 的改造实例,并且对该方法的调用在存储库中使用 await((

我做错了什么?

您的 API 调用抛出异常,因为没有网络连接(很可能是 UnknownHostException(。

将其包装在尝试捕获中并处理异常。

CoroutineExceptionHandler可能是一个解决方案。 https://kotlinlang.org/docs/reference/coroutines/exception-handling.html#coroutineexceptionhandler

打开飞行模式时,执行网络调用的协程将引发异常。 在您的情况下,您可以执行此类操作。

val handler = CoroutineExceptionHandler { _, exception -> 
//Handle your exception
}
init {
viewModelScope.launch(handler) {
videosRepository.refreshVideos()
}
}

相关内容

最新更新