Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Kotlin协同程序崩溃,没有有用的堆栈跟踪_Android_Kotlin_Kotlin Coroutines - Fatal编程技术网

Android Kotlin协同程序崩溃,没有有用的堆栈跟踪

Android Kotlin协同程序崩溃,没有有用的堆栈跟踪,android,kotlin,kotlin-coroutines,Android,Kotlin,Kotlin Coroutines,我的Android应用程序崩溃了,我在Logcat中看到了这个堆栈跟踪。它没有告诉我是哪行代码导致了问题 2021-05-05 09:13:33.143 1069-1069/com.mycompany.app E/AndroidRuntime: FATAL EXCEPTION: main Process: com.mycompany.app, PID: 1069 retrofit2.HttpException: HTTP 403 at retrofit2.KotlinExten

我的Android应用程序崩溃了,我在Logcat中看到了这个堆栈跟踪。它没有告诉我是哪行代码导致了问题

2021-05-05 09:13:33.143 1069-1069/com.mycompany.app E/AndroidRuntime: FATAL EXCEPTION: main
  Process: com.mycompany.app, PID: 1069
  retrofit2.HttpException: HTTP 403 
    at retrofit2.KotlinExtensions$await$2$2.onResponse(KotlinExtensions.kt:53)
    at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:161)
    at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:919)
有没有办法把它映射回我的代码,看看是哪个改造调用导致了它?我有一个代码如下的存储库:

suspend fun getSomeData():Stuff{
返回withContext(Dispatchers.IO){
val body=myRetroApi.getStuff()
...
我是否需要用contextbody包装每个
,以确保没有
Throwables
escape?我想如果有什么东西在那里抛出异常,它会记录错误,而不是使整个应用程序崩溃

编辑


我在问这个问题时搞砸了,把重点放在了错误的东西上。所以我去掉了“改装”标签。结果是
与上下文(Dispatchers.IO)
调用确实会按预期重新抛出
异常
,但当异常返回到
viewModelScope.launch
时,如果该块没有捕捉到它,应用程序将崩溃。

如果不处理异常,应用程序当然会崩溃

您可以添加一个try-catch来避免这种情况:

suspend fun getSomeData() {
   withContext(Dispatchers.IO) {
      try{
        val body = myRetroApi.getStuff()
        ...
      } catch (e : Exception){
         //your code
      }
...

如果不处理异常,应用程序当然会崩溃

您可以添加一个try-catch来避免这种情况:

suspend fun getSomeData() {
   withContext(Dispatchers.IO) {
      try{
        val body = myRetroApi.getStuff()
        ...
      } catch (e : Exception){
         //your code
      }
...

改型会给您一个403未经授权的HTTP异常。这可能是因为服务器没有传递任何其他错误消息,或者您需要捕获HttpException并检查消息。在任何情况下,这都不是改型问题,因此它只是传递从您调用的服务器获得的错误

最好为处理异常的API调用创建一个网络结果包装器和一个包装器函数

 sealed class NetworkResult<out T> {
    data class Success<T>(val data: T) : NetworkResult<T>()
    data class Error(val exception: Throwable, val message: String?) : NetworkResult<Nothing>()
 }
您可以这样做。请记住,实际的实现完全取决于您。但是,我建议在处理取消异常时使用runCatching

 sealed class NetworkResult<out T> {
    data class Success<T>(val data: T) : NetworkResult<T>()
    data class Error(val exception: Throwable, val message: String?) : NetworkResult<Nothing>()
 }

改型会给您一个403未经授权的HTTP异常。这可能是因为服务器没有传递任何其他错误消息,或者您需要捕获HttpException并检查消息。在任何情况下,这都不是改型问题,因此它只是传递从您调用的服务器获得的错误

最好为处理异常的API调用创建一个网络结果包装器和一个包装器函数

 sealed class NetworkResult<out T> {
    data class Success<T>(val data: T) : NetworkResult<T>()
    data class Error(val exception: Throwable, val message: String?) : NetworkResult<Nothing>()
 }
您可以这样做。请记住,实际的实现完全取决于您。但是,我建议在处理取消异常时使用runCatching

 sealed class NetworkResult<out T> {
    data class Success<T>(val data: T) : NetworkResult<T>()
    data class Error(val exception: Throwable, val message: String?) : NetworkResult<Nothing>()
 }

我认为如果有什么东西在那里抛出异常,它会记录一个错误,而不是使整个应用程序崩溃。
这是一个大胆的假设:)是的,我想是这样,尽管这是基于服务器端Java和后台线程的类似经验。让我感到惊讶的不是崩溃;更多的是堆栈跟踪没有指出我的代码中的任何内容。对于协同程序,您需要提供自己的错误处理,如果您只做一些研究,您可以找到很多关于这一点的信息,人们通常使用
safeApiCall
包装器来执行协同程序调用并返回结果。不过,一般来说,我认为大多数android框架都要求您处理异常如果你不为rxjava添加错误处理,它也会崩溃,这取决于你是如何使用它的。我认为协程异常处理非常复杂,很难记住所有关于其行为的奇怪规则。我的建议是在可能的最低点捕获可能的异常,并使用结果包装密封clas包装它们s、 这是Kotlin对Java检查异常的替代方案。
我认为如果有什么东西在那里抛出异常,它会记录错误,而不会使整个应用程序崩溃。
这是一个大胆的假设:)是的,我想是这样,尽管它是基于服务器端Java和后台线程的类似经验。让人吃惊的不是崩溃这让我很困惑;更重要的是堆栈跟踪没有指向我代码中的任何内容。对于需要提供自己的错误处理的协同路由,如果您只做一些研究,您可以找到很多关于这一点的信息,人们通常使用
safeApiCall
包装器来执行协同路由调用并返回结果绝大多数android框架都要求你自己处理异常,如果你不为rxjava添加错误处理,它也会崩溃,这取决于你如何使用它。我认为,协程异常处理非常复杂,很难记住所有关于其行为的奇怪规则。我的建议是以最低的速度捕获可能的异常可能点并使用结果包装密封类包装它们,这是Kotlin替代Java检查异常的方法。如何将异常从
withContext
传播到
getSomeData
?如果不可能,我想将getSomeData的返回类型从
T
更改为类似的类型
T?
Result
@RobN是的,由您决定如何表示。类似于
Result
的内容听起来是个不错的选择。这样您就不会丢失错误信息。您将如何将异常从
withContext
传播到
getSomeData
?如果不可能,那么我想将getSomeData的返回类型从
T
更改为类似
T?
Result
@RobN是的,由您决定如何表示。类似
Result
的选项听起来不错。这样您就不会丢失错误信息。