0

을 나는 다음과 같은 원격 URL에서 파일을 구문 분석 Jsoup를 사용 : 웹 사이트가 제한 시간 내에 응답하지 않으면Jsoup - 닫기가 호출되지 않습니다 - 안드로이드 StrictMode

Document doc = Jsoup.connect(urlString) 
    .timeout(5000) 
    .get(); 

예상 등의 SocketTimeoutException가 발생합니다 . 또한 StrictMode를 설정해 닫지 않은 리소스에 대해 경고합니다. 타임 아웃에서 StrictMode는 자원이 폐쇄되지 않았 음을 알려줍니다 :

A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks. 
java.lang.Throwable: Explicit termination method 'close' not called 
     at dalvik.system.CloseGuard.open(CloseGuard.java:184) 
     at java.io.FileInputStream.<init>(FileInputStream.java:80) 
     at libcore.io.DiskLruCache.get(DiskLruCache.java:391) 
     at libcore.net.http.HttpResponseCache.get(HttpResponseCache.java:98) 
     at android.net.http.HttpResponseCache.get(HttpResponseCache.java:204) 
     at libcore.net.http.HttpEngine.initResponseSource(HttpEngine.java:257) 
     at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:218) 
     at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:81) 
     at org.jsoup.helper.HttpConnection$Response.a(SourceFile:439) 
     at org.jsoup.helper.HttpConnection$Response.a(SourceFile:465) 
     at org.jsoup.helper.HttpConnection$Response.a(SourceFile:424) 
     at org.jsoup.helper.HttpConnection.execute(SourceFile:178) 
     at org.jsoup.helper.HttpConnection.get(SourceFile:167) 
     at com.example.$3.call(SourceFile:163) 
     at a.e.run(SourceFile:198) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 
     at java.lang.Thread.run(Thread.java:841) 

내가 Jsoup가 생성하는 자원을 닫는 방법을 볼 수 없습니다. 내가 어떻게 그럴 수 있니?

답변

0

Jsoup는

static Response execute(Connection.Request req, Response previousResponse) throws IOException { 
     Validate.notNull(req, "Request must not be null"); 
     String protocol = req.url().getProtocol(); 
     if (!protocol.equals("http") && !protocol.equals("https")) 
      throw new MalformedURLException("Only http & https protocols supported"); 

     // set up the request for execution 
     if (req.method() == Connection.Method.GET && req.data().size() > 0) 
      serialiseRequestUrl(req); // appends query string 
     HttpURLConnection conn = createConnection(req); 
     Response res; 
     try { 
      conn.connect(); 
      if (req.method() == Connection.Method.POST) 
       writePost(req.data(), conn.getOutputStream()); 

      int status = conn.getResponseCode(); 
      boolean needsRedirect = false; 
      if (status != HttpURLConnection.HTTP_OK) { 
       if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM || status == HttpURLConnection.HTTP_SEE_OTHER) 
        needsRedirect = true; 
       else if (!req.ignoreHttpErrors()) 
        throw new HttpStatusException("HTTP error fetching URL", status, req.url().toString()); 
      } 
      res = new Response(previousResponse); 
      res.setupFromConnection(conn, previousResponse); 
      if (needsRedirect && req.followRedirects()) { 
       req.method(Method.GET); // always redirect with a get. any data param from original req are dropped. 
       req.data().clear(); 

       String location = res.header("Location"); 
       if (location != null && location.startsWith("http:/") && location.charAt(6) != '/') // fix broken Location: http:/temp/AAG_New/en/index.php 
        location = location.substring(6); 
       req.url(new URL(req.url(), encodeUrl(location))); 

       for (Map.Entry<String, String> cookie : res.cookies.entrySet()) { // add response cookies to request (for e.g. login posts) 
        req.cookie(cookie.getKey(), cookie.getValue()); 
       } 
       return execute(req, res); 
      } 
      res.req = req; 

      // check that we can handle the returned content type; if not, abort before fetching it 
      String contentType = res.contentType(); 
      if (contentType != null && !req.ignoreContentType() && (!(contentType.startsWith("text/") || contentType.startsWith("application/xml") || contentType.startsWith("application/xhtml+xml")))) 
       throw new UnsupportedMimeTypeException("Unhandled content type. Must be text/*, application/xml, or application/xhtml+xml", 
         contentType, req.url().toString()); 

      InputStream bodyStream = null; 
      InputStream dataStream = null; 
      try { 
       dataStream = conn.getErrorStream() != null ? conn.getErrorStream() : conn.getInputStream(); 
       bodyStream = res.hasHeader("Content-Encoding") && res.header("Content-Encoding").equalsIgnoreCase("gzip") ? 
         new BufferedInputStream(new GZIPInputStream(dataStream)) : 
         new BufferedInputStream(dataStream); 

       res.byteData = DataUtil.readToByteBuffer(bodyStream, req.maxBodySize()); 
       res.charset = DataUtil.getCharsetFromContentType(res.contentType); // may be null, readInputStream deals with it 
      } finally { 
       if (bodyStream != null) bodyStream.close(); 
       if (dataStream != null) dataStream.close(); 
      } 
     } finally { 
      // per Java's documentation, this is not necessary, and precludes keepalives. However in practise, 
      // connection errors will not be released quickly enough and can cause a too many open files error. 
      conn.disconnect(); 
     } 

     res.executed = true; 
     return res; 
    } 

JSOUP HttpConnection 그래서 나는 그것이 문제가되지 않습니다 생각 소스에서 읽을 수있는 요청 후 연결이 완료 예외

의 경우에 닫힙니다.

+1

정보 주셔서 감사합니다. 나는 그것이 StrictMode로부터 거짓 긍정 (false positive)이 틀림 없다고 생각한다. –

관련 문제