尝试OkHttp3异步Get时,我不断收到java.net.SocketTimeoutException.这表明我没有将读取超时值设置得足够高(我认为默认值是10秒).
更大的问题是"如何防止这种异常?" 但是,除非有人有更好的初始策略,否则我的直接问题是,"如何为请求设置读取超时值?"
在我的代码中,我使用了Okttp Recipes页面中的信息
注意我的try-catch的前两行被注释掉了.那是因为我不能使用我需要的那种构建器(一个能够设置超时值,OkHttpClient.Builder)来添加头信息(Request.Builder).
我的代码看起来像这样:
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()); }
我在okhttp github网站上找到了一个似乎与此直接相关的报告问题.甚至还建议设置读取超时,如上所述已被注释掉,因为我无法想象如何将这种构建器带到配方页面上描述的异步请求上.
我的异常的堆栈跟踪如下,但请注意,大部分时间我都没有得到异常.堆栈跟踪:
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$000(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$2.read(Okio.java:138) 01-19 14:04:52.192: I/LogIt(25650): at okio.AsyncTimeout$2.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)
LordRaydenMK.. 15
代替
m_client = new OkHttpClient();
您应该使用以下构建器创建客户端:
m_client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build();
当您像这样创建客户端时,每个Request
执行的客户端(使用m_client.newCall(...)
)将使用构建器中指定的超时.
代替
m_client = new OkHttpClient();
您应该使用以下构建器创建客户端:
m_client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build();
当您像这样创建客户端时,每个Request
执行的客户端(使用m_client.newCall(...)
)将使用构建器中指定的超时.