OkHttp拦截器一直返回null并导致应用程序崩溃

3

我有一个使用自定义网络拦截器的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包围拦截器,并抛出错误以避免应用程序崩溃,但效果不佳。

拦截器代码:

Original Answer翻译成:"最初的回答"

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
        }

    }

请帮忙,寻找不会导致应用程序崩溃的异常控制方法。

Original Answer翻译成"最初的回答"


1
堆栈跟踪显示的是RequestsErrorInterceptor而不是你发布的TazuzuRequestsInterceptor - laalto
当你把所有的代码放在try/catch块中时,为什么还要使用那么多的if/else呢?:)) - beigirad
2个回答

5

几点说明

在拦截器中不应传递null

出了什么问题

null传递给下游链

你可以做什么

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
    }

}

如果你选择在没有网络连接时抛出异常,你可以在retrofit调用的onFailure()回调中处理所有内容。或者,如果你正在使用rxjava,你可以在错误回调处理程序上订阅错误。

了解更多


谢谢。那帮了我很多,让我更好地理解事物应该如何工作。 - holyubuntu
这个回答解决了你的问题吗? - Joshua de Guzman
是的,它确实做到了。我还为你的答案投了赞成票,但我的投票还没有被计算 :) - holyubuntu
没问题,很乐意帮助。 :) - Joshua de Guzman
太好了,这解决了我的问题。非常感谢! - Thien Ngan

0

当我尝试在主线程中发起请求时,出现了这个错误。尝试使用协程,只需将Retrofit请求调用包装在CoroutineScope中:

val apiService = RetrofitFactory.makeRetrofitService()

    CoroutineScope(Dispatchers.IO).launch {

        val response = apiService.myPostRequest()

        // process response...

    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接