Can I stop the stream that connects to the URL using httpConnection.connect ()?

I have a stream that connects to a url to receive some data.

Sometimes the httpConnection.connect(); method httpConnection.connect(); spent too much time to get an answer, and I want to limit the download dialog of this connection flow to 5 segments.

I tried adding timeouts to the code , but it does not work !!

 URL formattedUrl = new URL(url); URLConnection connection = formattedUrl.openConnection(); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); HttpURLConnection httpConnection = (HttpURLConnection) connection; httpConnection.setAllowUserInteraction(false); httpConnection.setInstanceFollowRedirects(true); httpConnection.setRequestMethod("GET"); httpConnection.setConnectTimeout(5000); httpConnection.setReadTimeout(5000); httpConnection.connect(); 

So, I have to stop the connection method and the stream when 5000 seconds have passed or when the used one has pressed the back key on the phone.

How can this be achieved? I can not find information about this work in android with the url connection thread.

thanks

+4
source share
3 answers

The timeout settings in the URLConnection are insufficient to provide the required timeout control. The reason is that:

  • setConnectTimeout () sets a timeout only to establish a connection to the server. Thus, the timeout will only work if the connection cannot be established within the set time period when the connection is opened.

  • setReadTimeount () sets a timeout to read available data. To do this, the timeout will be triggered only if any single block of read operations is longer than the set amount of time. Thus, even with a slow connection, it is entirely possible that each read operation never approaches the timeout threshold, but the total amount of time to read all the data is quite long.

One solution to applying a timeout to the entire reader is to use the concurrency features found in Java 5 and later. In particular, using ExecutorService and Future should be enough.

 Runnable task = new Runnable() { public void run() { // original code to read data from a URL } }; ExecutorService executor = Executors.newSingleThreadExecutor(); // or any other implementation Future<?> future = executor.submit(task); try { future.get(5, TimeUnit.SECONDS); // wait 5 seconds for task to complete // success } catch (TimeoutException ex) { // handle timeout } finally { executor.shutdownNow(); // cleanup } 
+3
source

Brent Worden's answer is on the right track. But there is a problem with its solution. If the task timeout fires, the thread that calls future.get will receive an exception as expected. However, the worker thread that executed the Runnable.run() method can still stand by while waiting for the connection to complete or read.

The solution to this is difficult. As far as I know, the only reliable way to untie a thread that is waiting to read or write a socket or socket is to call the close() of the Socket object. And the problem with using this approach (here) is that the standard HttpUrlConnection object HttpUrlConnection not provide a Socket object.

My recommendation would be to use the Apache Http client libraries. This question explains how to abort a request if you are using HttpClient: Cancel the HttpClient request

+3
source

You only need to call URLConnection.setConnectTimeout (millis) to achieve what you are asking. If the specified timeout expires, a SocketTimeoutException .

 try { HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection(); con.setConnectTimeout(5000); //set timeout to 5 seconds } catch (java.net.SocketTimeoutException e) { //DO SOMETHING } catch (java.io.IOException e) { //DO SOMETHING } 

It is worth noting that he says the following:

Some non-standard implementation of this method may ignore the specified timeout. To see the set connection timeout, call getConnectTimeout ().

0
source

Source: https://habr.com/ru/post/1438109/


All Articles