java OkHttp3 SocketTimeoutException (在 Android 应用程序中) -- 如何为异步请求设置读取超时?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41750024/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 06:08:07  来源:igfitidea点击:

OkHttp3 SocketTimeoutException (in Android app) -- How to set read timeout for asynchronous request?

javaandroidasynchronousokhttp3socket-timeout-exception

提问by Alyoshak

I keep getting a java.net.SocketTimeoutException when attempting an OkHttp3 asynchronous Get. This suggests that I haven't set the read timeout value high enough (I think the default is 10 seconds).

尝试 OkHttp3 异步获取时,我不断收到 java.net.SocketTimeoutException。这表明我没有将读取超时值设置得足够高(我认为默认值为 10 秒)。

The larger question is "How to prevent this exception?" but, unless someone has a better initial strategy, my immediate question is, "How to set a read timeout value for the request?"

更大的问题是“如何防止这种异常?” 但是,除非有人有更好的初始策略,否则我的直接问题是,“如何为请求设置读取超时值?”

In my code I've used the information from the Okttp Recipes page here

在我的代码中,我在这里使用了 Okttp Recipes 页面中的信息

Notice the first two lines of my try-catch are commented out. That's because I cannot use the kind of builder (one capable of setting a timeout value, OkHttpClient.Builder) that I need in order to add header info (Request.Builder) .

注意我的 try-catch 的前两行被注释掉了。那是因为我不能使用我需要的那种构建器(一种能够设置超时值的构建器,OkHttpClient.Builder)来添加标头信息 (Request.Builder) 。

My code looks like this:

我的代码如下所示:

    m_client = new OkHttpClient();


    try
    {
        //OkHttpClient.Builder bldr = m_client.newBuilder();
        //bldr.readTimeout(0, TimeUnit.SECONDS);

        Request.Builder reqBuilder = new Request.Builder();

        reqBuilder.addHeader("authorization", getToken());

        Request request = reqBuilder.url("http://plusdev.kooklah.com/api/v2_1/items/get").build();

        m_client.newCall(request).enqueue(new Callback()
        {
            @Override
            public void onFailure(Call call, IOException e)
            {
                Log.i("Logit", "Inside onFailure() -- IOException: " + e.getMessage() + " ----- stack trace: " + UtilGen.exceptionToString(e));

                runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                       // do stuff on UI thread
                    }
                });
            }

            @Override
            public void onResponse(Call call, final Response responseIn)
            {
                try
                {
                    m_sServerResponse = responseIn.body().string();
                }
                catch (Exception ex)
                {
                    Log.i("LogIt", "          ---Inside onResponse() -- Exception occurred. ex: " + ex.toString());
                }

                runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        Log.i("LogIt", "          ---Inside onResponse() -- inside run().");
                        if (!m_sServerResponse.isEmpty())
                        {
                            Log.i("LogIt", "          ---Inside onResponse() -- inside run() -- Success");
                            processDownloadedAssessments(m_sServerResponse);
                        }
                    }
                });
            }
        });
    }
    catch (Exception ex)
    {
        Log.i("LogIt", "ex: " + ex.getMessage());
    }

I found a reported issue that seems directly related, here, on the okhttp github site. There's even a recommendation to set the read timeout, which as mentioned above has been commented out because I cannot figure how to bring that kind of builder to bear on an async request as described on the Recipe page.

我发现了一个报告的问题似乎是直接相关的,在这里,在okhttp GitHub的网站。甚至有一个设置读取超时的建议,如上所述,它已被注释掉,因为我无法弄清楚如何使这种构建器承担在 Recipe 页面上描述的异步请求。

The stack trace for my exception is below, but be aware that most of the time I don't get the exception. Stack trace:

我的异常的堆栈跟踪如下,但请注意,大部分时间我都没有收到异常。堆栈跟踪:

01-19 14:04:52.192: I/LogIt(25650): Inside onFailure() -- IOException: null ----- stack trace: java.net.SocketTimeoutException
01-19 14:04:52.192: I/LogIt(25650):     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
01-19 14:04:52.192: I/LogIt(25650):     at java.net.PlainSocketImpl.access
m_client = new OkHttpClient();
0(PlainSocketImpl.java:37) 01-19 14:04:52.192: I/LogIt(25650): at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237) 01-19 14:04:52.192: I/LogIt(25650): at okio.Okio.read(Okio.java:138) 01-19 14:04:52.192: I/LogIt(25650): at okio.AsyncTimeout.read(AsyncTimeout.java:236) 01-19 14:04:52.192: I/LogIt(25650): at okio.RealBufferedSource.indexOf(RealBufferedSource.java:325) 01-19 14:04:52.192: I/LogIt(25650): at okio.RealBufferedSource.indexOf(RealBufferedSource.java:314) 01-19 14:04:52.192: I/LogIt(25650): at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:210) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http1.Http1Codec.readResponse(Http1Codec.java:191) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:132) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:54) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.RealCall$AsyncCall.execute(RealCall.java:129) 01-19 14:04:52.192: I/LogIt(25650): at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 01-19 14:04:52.192: I/LogIt(25650): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 01-19 14:04:52.192: I/LogIt(25650): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 01-19 14:04:52.192: I/LogIt(25650): at java.lang.Thread.run(Thread.java:818)

回答by LordRaydenMK

Instead of

代替

m_client = new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .writeTimeout(10, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .build();

you should create the client using a builder like:

您应该使用如下构建器创建客户端:

##代码##

When you create the client like this each Requestexecuted whit this client (using m_client.newCall(...)) will use the timeouts specified in the builder.

当您像这样创建客户端时,每个Request执行此客户端(使用m_client.newCall(...))将使用构建器中指定的超时。