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:2和Kotlin的不可修补异常_Android_Kotlin_Retrofit2 - Fatal编程技术网

Android:2和Kotlin的不可修补异常

Android:2和Kotlin的不可修补异常,android,kotlin,retrofit2,Android,Kotlin,Retrofit2,关于最新的改装2和Kotlin,我遇到了一个非常棘手的问题。 客户端希望通过2连接到服务器 val client = OkHttpClient.Builder() .addInterceptor(object: Interceptor { override fun intercept(chain: Interceptor.Chain): Response { try{

关于最新的改装2和Kotlin,我遇到了一个非常棘手的问题。

客户端希望通过2连接到服务器

        val client = OkHttpClient.Builder()
            .addInterceptor(object: Interceptor {
                override fun intercept(chain: Interceptor.Chain): Response {
                    try{
                        chain.proceed(chain.request());
                        return chain.proceed(chain.request());
                     }catch(e:Exception){
                        e.printStackTrace()
                      //called
                     }

                    return chain.proceed(chain.request());//leads to crash
                }
            })
            .readTimeout(10, TimeUnit.SECONDS).build()
服务的创建方式如下所示:

        try {//try/catch here is useless -> not called
        retrofit = Retrofit.Builder()
                .baseUrl(Constants.SERVER_BASEURL + ":3000")
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
        }catch (e:Exception){
            e.printStackTrace()
        }
java.net.ConnectException: Failed to connect to /XXXXXXX:3000
    at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.kt:270)
    at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:176)
    at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:236)
    at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:109)
    at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:77)
    at okhttp3.internal.connection.Transmitter.newExchange$okhttp(Transmitter.kt:162)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:35)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:84)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:71)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
    at com.project.app.Helpers.MasterViewModel$getRetrofitClient$client$1.intercept(MasterViewModel.kt:118)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
    at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:215)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
    at okhttp3.RealCall$AsyncCall.run(RealCall.kt:136)
    at java.util.concurrent.ThreadPoolExecutor.processTask(ThreadPoolExecutor.java:1187)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:784)
任何函数都是以协同路由方式调用的,如下所示:

@POST("/users/me/logout")
suspend fun logout(@Header("Authorization") token: String): ResponseBody
所有这些都可以正常工作,但一旦与服务器失去连接,就不可能捕捉到错误,这会自动导致应用程序崩溃。

对于脱机服务器,异常情况如下所示:

        try {//try/catch here is useless -> not called
        retrofit = Retrofit.Builder()
                .baseUrl(Constants.SERVER_BASEURL + ":3000")
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
        }catch (e:Exception){
            e.printStackTrace()
        }
java.net.ConnectException: Failed to connect to /XXXXXXX:3000
    at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.kt:270)
    at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:176)
    at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:236)
    at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:109)
    at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:77)
    at okhttp3.internal.connection.Transmitter.newExchange$okhttp(Transmitter.kt:162)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:35)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:84)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:71)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
    at com.project.app.Helpers.MasterViewModel$getRetrofitClient$client$1.intercept(MasterViewModel.kt:118)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
    at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:215)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
    at okhttp3.RealCall$AsyncCall.run(RealCall.kt:136)
    at java.util.concurrent.ThreadPoolExecutor.processTask(ThreadPoolExecutor.java:1187)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:784)
据我所知:

  • 在第一个代码块中截获的事件显示异常被抛出

    继续(chain.request())

    由于“intercept”的返回值是“Response”,因此可以认为只是返回一个伪响应。但这也会导致新的问题,因为创建这样一个虚拟响应非常困难,而且您会丢失所有请求调用。最好的方法是暂停发出的请求,直到服务器重新连接

  • 第二个代码块中的try,catch块实际上是无用的。它对防止崩溃没有任何作用,因为崩溃发生在请求/响应管道内,可能发生在一个通过改装来调用挂起函数的协同程序内

  • 不管服务器是否超时或根本不存在,在任何连接问题发生时,都会抛出不可修补的异常,应用程序将崩溃
我想,这是一个尚未解决的普遍问题。

也有类似的问题,比如这个:

但是解决方案在这里无法工作,因为它不会阻止调用关键部分“chain.procedue(chain.request());”


除了forking建议之外,任何帮助都将不胜感激。

我想您不需要尝试/捕获您的改装初始化(也不需要自定义
OkhttpClient
),而是每次呼叫服务。创建
apiClient
并重用以调用服务:

val apiClient = retroft.create(TourService::class.java)
...
//calling API:
try{
    val responseBody = apiClient.logout("some token")
}catch(x: Exception){
    //catch app crash
    when(x){
        is ConnectException -> //TODO: handle connection error       
        is UnknownHostException ->  //TODO: handle no internet connection error
    }
}

我想您不需要
尝试/catch
您的改装初始化(也不需要自定义
OkhttpClient
),而是需要每次调用服务。创建
apiClient
并重用以调用服务:

val apiClient = retroft.create(TourService::class.java)
...
//calling API:
try{
    val responseBody = apiClient.logout("some token")
}catch(x: Exception){
    //catch app crash
    when(x){
        is ConnectException -> //TODO: handle connection error       
        is UnknownHostException ->  //TODO: handle no internet connection error
    }
}

事实上,我似乎错过了协同程序中的一点,我没有抓住例外。谢谢:)事实上,我似乎错过了协同程序中的一点,我没有抓住例外。谢谢:)