16

I am using org.apache.http and I've this code:

DefaultHttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);

HttpResponse resp = client.execute(get);
HttpEntity entity = resp.getEntity();

InputStream input = entity.getContent();

...
//Read the bytes from input stream

This is the code I am using to download files over Http, I want to cancel the connection(may be user chooses to) What is the graceful way to close the connection. I found 2 ways, Both cancels the download.

  1. Closing inputsteram, input.close(); which causes IOException.
  2. Aborting HttpGet object, get.abort() causes SocketException.

I have try catch, so no erros, but without throwing exception, is there a way to cancel or abort the connection?

What is the right way to go about it ?

KV Prajapati
  • 93,659
  • 19
  • 148
  • 186
sat
  • 40,138
  • 28
  • 93
  • 102
  • yes, in doInBackground() I read data, in onCancelled I need a proper way to cancel the download, I am currently doing get.abort() from the above the code. – sat Sep 03 '11 at 11:14
  • I think that you cannot cancel the get. You just cancel the async task, and in the onCancelled() you do whatever you want, i.e. ignore any results you may get. Check this post also: http://stackoverflow.com/questions/4880363/cancelled-asynctask-hangs-new-httprequests – Dimitris Makris Sep 03 '11 at 11:18
  • As I said, I am doing the same, in onCancelled method I abort the download using get.abort() and its happening without any problem, but it throws socketException which I am catching, My doubt is without catching exception(or say throwing exception) How to abort it. – sat Sep 03 '11 at 11:24
  • 1
    you can try `EntityUtils.consume(entity)` look this [answer][1] [1]: http://stackoverflow.com/a/7152466/885152 – secondflying Sep 15 '12 at 12:47
  • Consume is the correct way. No resources will be wasted, Java (barring native code) doesn't have any "true memory leaks". – Mitch Connor Sep 18 '12 at 20:47

4 Answers4

3

The proper way doing this is sending FIN value to the server side.

How ever in android you do not have the option to be involved in this level, so you can implement by your self using C, or use one of the methods you mention in your question.

Ilya Gazman
  • 31,250
  • 24
  • 137
  • 216
3

Using HttpUriRequest#about is the right way in my opinion. This will cause immediate termination of the underlying connection and its eviction from the connection pool. Newer versions of HttpClient (4.2 and newer) intercept SocketExceptions caused by premature request termination by the user. The problem is that Google ships a fork of HttpClient based on an extremely outdated version (pre-beta1). If you are not able or willing to use a newer version of HttpClient your only option is to catch and discard SocketException in your code.

ok2c
  • 26,450
  • 5
  • 63
  • 71
2

Use this

client.getConnectionManager().closeExpiredConnections();
client.getConnectionManager().shutdown();

Now you can decide where would you like to write these 2 lines in code.. It will close the connection using the DefaultHttpClient object that you created.

Let me know if this helps you.

Gautam Mandsorwale
  • 1,580
  • 1
  • 18
  • 27
  • Sorry, indeeed I am looking for the same feature but with spring android rest template and it is quite different. – Snicolas Sep 13 '12 at 16:26
  • hmmm.... Just a question are you using the REST api for doing web service calls. Coz Ive used them and the above 2 lines have helped me to close connection as per the requirement... :) – Gautam Mandsorwale Sep 14 '12 at 06:16
  • 1
    What do you mean by REST api, spring android RestTemplate ? Cause I tried with this api to get access to the HttpClient, and I could execute the two lines but nothing works and connection is opened and blocks others as long as time out did not expire. – Snicolas Sep 14 '12 at 06:38
  • [This](http://timewasted.net/?p=127) is what i meant by REST api web service call.. – Gautam Mandsorwale Sep 14 '12 at 09:56
  • I am using the spring-android resttemplate which may rely on the apache client apis, depending on the android version your code is running on. – Snicolas Sep 14 '12 at 11:18
  • Hmmm...is that a requirement for your app to use spring rest template? Coz the code you posted above seems to be a normal api call similar to the link i posted in the above comment.. – Gautam Mandsorwale Sep 14 '12 at 11:24
  • Yes it is. Sorry (btw, I gave a bounty for the question, but it's not mine). – Snicolas Sep 14 '12 at 11:33
  • Okay, hope you find the solution. – Gautam Mandsorwale Sep 14 '12 at 12:14
  • It looks like there is no solution. Quite a complex problem and Spring android makes it deep under the surface. Any how, I do believe the android network layer doesn't fully support this. – Snicolas Sep 14 '12 at 18:55
2

Try to cancel the task when you want to interrupt the connection: task.cancel(true); This will cancel the task and the threads running in it. Check this for reference: public final boolean cancel (boolean mayInterruptIfRunning)

Since: API Level 3 Attempts to cancel execution of this task. This attempt will fail if the task has already completed, already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.

Calling this method will result in onCancelled(Object) being invoked on the UI thread after doInBackground(Object[]) returns. Calling this method guarantees that onPostExecute(Object) is never invoked. After invoking this method, you should check the value returned by isCancelled() periodically from doInBackground(Object[]) to finish the task as early as possible.

Parameters mayInterruptIfRunning true if the thread executing this task should be interrupted; otherwise, in-progress tasks are allowed to complete. Returns false if the task could not be cancelled, typically because it has already completed normally; true otherwise

Samer
  • 536
  • 3
  • 5