首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >调用REST ->致命异常的Coroutines:

调用REST ->致命异常的Coroutines:
EN

Stack Overflow用户
提问于 2019-10-01 07:50:10
回答 2查看 2K关注 0票数 6

我需要从REST中获取一些数据,当我连接4G或wifi时,一切正常,但当我处于飞机模式时,应用程序会崩溃:"E/AndroidRuntime:致命例外: main“

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

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

ViewModel

代码语言:javascript
运行
复制
private val viewModelJob = SupervisorJob()
private val viewModelScope = CoroutineScope(viewModelJob + Dispatchers.Main)
init {
        viewModelScope.launch {
            videosRepository.refreshVideos()
        }
    }

仓库

代码语言:javascript
运行
复制
suspend fun refreshVideos() {
        withContext(Dispatchers.IO) {
            val playlist = Network.devbytes.getPlaylist().await()
            //database.videoDao().insertAll(*playlist.asDatabaseModel())
        }
    }

服务

代码语言:javascript
运行
复制
/**
 * 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 -> coroutine和Dispatchers.Main

调用存储库->挂起函数,该函数使用Dispatchers.IO启动协同服务。

通过对象网络调用服务->,我得到一个带有getPlaylist()的更新实例,该实例返回一个延迟,对该方法的调用位于存储库中,其中包含一个await()

我做错什么了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-01 07:59:30

您的API调用会引发异常,因为没有网络连接(很可能是UnknownHostException)。

把它包装在一个尝试-捕获和处理异常。

票数 6
EN

Stack Overflow用户

发布于 2019-10-01 08:09:09

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

当您打开飞机模式时,进行网络呼叫的协同线将抛出异常。在你的情况下,你可以这样做。

代码语言:javascript
运行
复制
    val handler = CoroutineExceptionHandler { _, exception -> 
            //Handle your exception
        }
    init {
        viewModelScope.launch(handler) {
            videosRepository.refreshVideos()
        }
    }
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58180265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档