OkHttp拦截器不断返回null并导致应用崩溃

时间:2019-01-22 09:14:25

标签: android kotlin retrofit okhttp

我有一个OkHttp客户端,该客户端使用我的自定义网络拦截器将令牌插入请求标头中。

我不断收到异常

E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher 
   Process: com.edstart.tazuzu, PID: 32093
   java.lang.NullPointerException: interceptor com.edstart.tazuzu.RestAPI.RequestsErrorInterceptor@2bde70f returned null
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:157)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
       at com.edstart.tazuzu.RestAPI.TazuzuRequestsInterceptor.intercept(TazuzuRequestsInterceptor.kt:30)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
       at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
       at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
       at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
       at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
       at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
       at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
       at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
       at java.lang.Thread.run(Thread.java:764)

我尝试用try / catch包围拦截器。并抛出错误以避免应用崩溃,但效果不佳。

拦截器代码:

package com.edstart.tazuzu.RestAPI

import android.util.Log
import com.edstart.tazuzu.Managers.ServerManager
import okhttp3.Interceptor
import okhttp3.Response
import java.net.InetAddress
import kotlin.Exception

/**
 * interceptor for the tazuzu api requests to insert the token before the request
 * send to the server (for authentication)
 */
class TazuzuRequestsInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain?): Response? {
        try {

            if (!isInternetAvailable()) {
                throw Exception()
            } else {
                var request = chain?.request()

                if (request != null) {
                    val builder = request.newBuilder()
                    if (builder != null) {
                        builder.addHeader("x-access-token", ServerManager.token)

                        request = builder.build()
                        if (request != null && chain != null) {
                            return chain.proceed(request)
                        }
                    }
                }
            }
        } catch (e: java.lang.Exception) {
            Log.e("###", e.toString())
            throw e
        }
        return null
    }

    private fun isInternetAvailable(): Boolean {
        return try {
            val ipAddr = InetAddress.getByName("google.com")
            //You can replace it with your name
            !ipAddr.equals("")

        } catch (e: Exception) {
            false
        }

    }

请提供帮助,以一种不会导致应用崩溃的方式控制异常。

3 个答案:

答案 0 :(得分:0)

您不应使用null方法返回intercept。返回类似这样的内容:

override fun intercept(chain: Interceptor.Chain?): Response? {
    // ...
    return chain?.proceed(request);
}

答案 1 :(得分:0)

少量笔记

您不应在拦截器中传递class ErrorHandlingInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() val response = chain.proceed(request) if (!isInternetAvailable()) { // Do your thing // 1. Either throw a generic exception // 2. Throw an exception with your own custom status code that can be checked on the callbacks // 3. Create an interface callback // example throw invocation throw Exception() } else { val builder = request.newBuilder() builder?.let { builder -> builder.addHeader("x-access-token", ServerManager.token) } request = builder.build() // No need for this additional checks // if (request != null && chain != null) { ... } return chain.proceed(request) } } } private fun isInternetAvailable(): Boolean { return try { val ipAddr = InetAddress.getByName("google.com") //You can replace it with your name !ipAddr.equals("") } catch (e: Exception) { false } }

出了什么问题

空值传递给下游链

您可以做什么

onFailure()

例如,如果您选择在没有互联网连接时引发异常,则可以只处理retrofit调用的rxjava回调中的所有操作。

或者,如果您使用的是CreateEvent,则可以在错误回调处理程序上订阅错误。

了解更多信息

答案 2 :(得分:0)

尝试在主线程中启动请求时出现此错误。尝试使用协程,只需使用 CoroutineScope 包装您的 Retrofit-request 调用:

val apiService = RetrofitFactory.makeRetrofitService()

    CoroutineScope(Dispatchers.IO).launch {

        val response = apiService.myPostRequest()

        // process response...

    }