2017-01-19 11 views
0

OkHttp3 비동기 Get을 시도 할 때 java.net.SocketTimeoutException이 계속 발생합니다. 이것은 읽기 타임 아웃 값을 충분히 높게 설정하지 않았 음을 의미합니다 (기본값은 10 초라고 생각합니다).OkHttp3 SocketTimeoutException (안드로이드 애플 리케이션에서) - 비동기 요청에 대한 읽기 시간 제한을 설정하는 방법?

큰 질문은 "이 예외를 방지하는 방법"입니다. 하지만 누군가가 더 좋은 초기 전략을 갖고 있지 않으면 즉각적인 질문은 "요청에 대한 읽기 시간 초과 값을 설정하는 방법"입니다. 내 코드에서

나는 나의 시도 - 캐치의 처음 두 줄이 주석하고있는 Okttp 조리법 페이지 here

공지 사항의 정보를 사용했습니다. 헤더 정보 (Request.Builder)를 추가하려면 필요한 빌더 (시간 초과 값을 설정할 수있는 것, OkHttpClient.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의 사이트에, here을 직접 관련된 것보고 된 문제를 발견했다. 읽기 타임 아웃을 설정하는 권장 사항조차도 있습니다. 위에서 언급 한 바와 같이 비공식 요청시 해당 종류의 빌더를 가져 오는 방법을 알 수 없기 때문에 주석 처리되었습니다.

내 예외에 대한 스택 추적은 아래에 있지만 대부분의 경우 예외가 발생하지 않는다는 것을 알고 있어야합니다. 스택 추적 :

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) 
+0

'OkHttpClient' 빌더와'Request' 빌더는 두 개의 다른 클래스입니다. 'OkHttpClient' 빌더에서 타임 아웃을 설정하면 모든 요청에 ​​적용됩니다. 헤더를 개별 요청에 대한'Request' 빌더로 설정합니다. – LordRaydenMK

+0

매우 사실이지만 타임 아웃 값을 설정 한 후 요청을 요청으로 가져 오는 방법은 무엇입니까? – Alyoshak

+0

당신은 지정된 타임 아웃을 가진 빌더를 사용하여 빌드 된'OkHttpClient'를 사용하여'Request'를 실행합니다. – LordRaydenMK

답변

5

대신

m_client = new OkHttpClient(); 

의이 같은 빌더를 사용하여 클라이언트 작성해야합니다 : 각 Request 실행 오순절이 같은이 클라이언트를 클라이언트를 만들 때

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

을 (m_client.newCall(...) 사용)은 빌더에 지정된 시간 초과를 사용합니다.

+0

내가 요리하는 냄새가납니다. 조금만 종료해야하지만 최대한 빨리 시도 할 것입니다. 내일이 될지도 모른다. 감사. – Alyoshak

+0

그건 내 문제 였어. OkHttpClient 빌더에서 timeout을 설정 한 후에 build() 호출을 사용하지 않았다. – Alyoshak

+0

타임 아웃시 해당 예외는 무엇입니까? –