无网络时OkHttp拦截器触发空指针异常问题求助
先看你日志里的核心报错:
java.lang.NullPointerException: interceptor com.cba.tymecoach.CustomResponseInterceptor@fff543d returned null
这就直接点明了问题根源:你的CustomResponseInterceptor拦截器在某些场景下返回了null,而OkHttp的拦截器链有严格要求——每个拦截器必须返回一个非空的Response对象(要么调用chain.proceed(request)继续执行后续拦截器,要么自己构建一个合法的Response返回),返回null就会触发这个空指针。
为什么只在无网络切前台时出现?
大概率是你的拦截器在处理网络异常(比如无网络时请求失败)的逻辑有漏洞:网络正常时,请求能顺利走完拦截器链,chain.proceed(request)会返回有效响应,所以不会出问题;但当应用切前台时,可能有 pending 的请求被触发,此时无网络导致拦截器处理异常时直接返回了null,才触发了崩溃。
具体修复方案
1. 检查并修复CustomResponseInterceptor的intercept方法
无论什么情况,这个方法绝对不能返回null,给你两种常见的修复思路:
思路一:捕获网络异常,返回合法错误响应
如果你的拦截器里有网络请求逻辑,记得捕获IOException(无网络、连接超时等都属于这类),在catch块里构建一个标准的错误响应返回,或者直接抛出异常让上层处理:
class CustomResponseInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { return try { val response = chain.proceed(chain.request()) // 这里放你的自定义响应处理逻辑,比如解析响应头、统一处理错误码等 response } catch (e: IOException) { // 无网络时构建一个503服务不可用的响应 Response.Builder() .request(chain.request()) .protocol(Protocol.HTTP_1_1) .code(503) .message("Network unavailable") .body(ResponseBody.create(null, "")) // 空body,也可以根据需求返回自定义内容 .build() // 如果不想在这里处理,也可以直接抛出异常,让调用方的回调处理: // throw e } } }
思路二:补全所有分支的返回值
如果你的拦截器里有if-else这类分支判断,要确保每个分支都有明确的Response返回,不要出现某个分支漏写return导致默认返回null的情况:
class CustomResponseInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() if (needCustomHandle(request)) { // 自定义处理逻辑,返回处理后的响应 return handleCustomRequest(request, chain) } else { // 之前可能这里没写return,或者返回了null,现在必须返回有效Response return chain.proceed(request) } } private fun handleCustomRequest(request: Request, chain: Interceptor.Chain): Response { // 你的自定义处理逻辑,确保返回非空Response return chain.proceed(request) } }
2. 验证修复效果
关闭设备网络,把应用切到后台再切回前台,触发相关请求,确认空指针异常不再出现。
关键提醒
OkHttp在RealInterceptorChain.proceed()方法里会校验拦截器的返回值,如果是null就直接抛出空指针,这是框架的强制要求,所以只要保证拦截器的intercept方法永远返回非空Response,这个问题就解决了。
内容的提问来源于stack exchange,提问作者Manian

