I am developing an android application that rely very much on internet, I retrieve data frequently using this RestClient Class, that wrap some detail on using DefaultHttpCli
Use the threading primitives. Have a flag running
and set it to true
initially. Do your REST requests in a while(running)
loop.
In your onPause()
, set the running flag to false
.
The RestClient
object your using doesn't expose any interrupt()
method of DefaultHttpClient
(which is the backing object doing most of the work). Not a problem - the DefaultHttpClient doesn't seem to have any interrupt or abort functionality to expose in the first place.
So, your left with a blocking operation on client.Execute()
.
Your half way to having a solution - which is to put the blocking operation into a Thread. Where your falling down is your architecture - your using a Thread/Listener setup which doesn't give you alot of wiggle room.
Try switching your anonymous Thread
to an AsyncTask
. This won't solve the problem of you're client.Execute()
from blocking but will allow you to throw away the listener (replacing it with onProgressUpdate()
or onPostExecute()
).
What this will do is allow you call task.cancel()
, signalling to the Task it is no longer needed. This will allow you to reassign a new AsyncTask, orphaning the cancelled task, the orphaned thread will then finish quickly as its able and die quietly while the rest of your application gets on with what it needs to.
((On an unrelated note, "Execute()" is a method and shouldn't be capitalised))
I suggest you take a look at the ClientConnectionManager
interface. This allows you to do stuff like releasing a connection, shutting down a connection etc. You may need to enhance the implementation of RestClient
though - since your RestClient
does not expose the underlying DefaultHttpClient
object (from which you can get to the ClientConnectionManager
using the getClientConnectionManager()
method).
I had the same issue and was able to find a fix. Here is what I did:
I used CloseableHttpClient along with other related classes, instead of the DefaultHttpClient that by default comes with Android.
These classes are from https://hc.apache.org/downloads.cgi. OR for direcet access: http://apache.mirrors.hoobly.com//httpcomponents/httpclient/binary/httpcomponents-client-4.3.2-bin.tar.gz
With this, calling the abort() method on the Request object will actually halt the connection. However, using this library is not the solution; reason being that Android already has the outdated HTTPCLIENT library inbuilt, and most classes in the library pointed to by the above link would appear to be missing at runtime.
The problem is that both the packages in the above library and the inbuilt org.apache httpclient package have same namespace, and would result in the use of only the inbuilt org.apache classes provided by Android at compilation.
An example of this issue is found here: java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INSTANCE.
Thanks to the guys who provided http://code.google.com/p/httpclientandroidlib/ as an option (found in the answer section of java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INSTANCE)
Recommendation: one place to actually cancel an http request could be within OnCancel Listener of a progress dialog, instead of the AyncTask's onCancelled() callback method.