How to cancel DefaulHttpClient execution process i

2020-02-29 23:47发布

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 DefaultHttpClient to do network request.

And I always use different thread to do the HTTP request, I create a class like this:

public class AsyncWorker {

    final String SERVER_URL = "http://api.blabla.com";
    RestClient client = new RestClient();

    public void requestHttp(final String url, final ArrayList<NameValuePair> params, final RequestListener listener) {
        new Thread(new Runnable() {

            public void run() {
                try {
                    client.setUrl(url);
                    client.setParams(params);
                    client.Execute(RestClient.RequestMethod.POST);
                    String response = client.getResponse();
                    listener.onComplete(response);
                } catch (Exception ex) {
                    Log.d("LOGIN", ex.getMessage());
                }
            }
        }).start();
    }
    etc...

So whenever I need to do a HTTP request, I only need to create AsyncWorker object, and provide the RequestListener callback interface.

But the problem is, how can I cancel the HTTP Request when the user press the back/cancel button? and in this case the application still is in one activity, for example I create a dialog, and the user do a request from that dialog, and then back button pressed, the dialog dismissed, and I need to cancel the request on that time.

4条回答
Lonely孤独者°
2楼-- · 2020-02-29 23:57

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).

查看更多
Ridiculous、
3楼-- · 2020-03-01 00:00

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.

查看更多
▲ chillily
4楼-- · 2020-03-01 00:10

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

查看更多
Root(大扎)
5楼-- · 2020-03-01 00:20

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.

查看更多
登录 后发表回答