如何在多线程中取消DefaulHttpClient的执行过程[英] How to cancel DefaulHttpClient execution process in multithread

本文是小编为大家收集整理的关于如何在多线程中取消DefaulHttpClient的执行过程的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在开发一个非常依赖Internet的Android应用程序,我经常使用此 RestClient类,该包含一些有关使用DefaulthtpClient进行网络请求的细节.

我总是使用不同的线程来执行HTTP请求,我创建了这样的类:

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

因此,每当我需要执行HTTP请求时,我只需要创建AsyncWorker对象,并提供RequestListener回调接口.

但是问题是,当用户按 Back/Cancel按钮时,如何取消HTTP请求?在这种情况下,该应用程序仍然存在于一个活动中,例如,我创建一个对话框,用户从该对话框中执行请求,然后按下后按钮,对话框被解散,我需要在此时间取消请求.

推荐答案

我建议您查看ClientConnectionManager接口.这使您可以执行诸如释放连接,关闭连接等的事情,但您可能需要增强RestClient的实现 - 因为您的RestClient不会暴露基础DefaultHttpClient对象(您可以从中获得.使用ClientConnectionManager使用getClientConnectionManager()方法).

其他推荐答案

我也有相同的问题,并且能够找到修复程序.这是我所做的:

我使用 ClosableHttpClient 以及其他相关类别,而不是默认情况下随附的 defaulthttpclient .

这些类来自 https://hc.apache.org/downloads.cgi .或用于目录的访问: http://apache.mirrors.hoobly.com//httpcomponents/httpclient/binary/binary/httpcomponents-client-4.3.2-bin.tar.tar.gz

这样,在请求对象上调用 abort()方法实际上将停止连接.但是,使用此库不是解决方案.原因是Android已经在内置了过时的HTTPCLIENT库,并且图书馆中的大多数类别由上述链接指向的大多数类似乎都在运行时丢失.

问题在于上面库中的包装和内置org.apache httpclient软件包都有相同的名称空间,并且只会导致汇编时提供的Android类的Innopache类.

.

此处找到了此问题的一个示例: java. lang.nosuchfielderror:org.apache.http.message.basiclineformatter.instance .

感谢提供 作为一个选项(在 of Answer段中找到java.lang.nosuchfielderror:org.apache.http.message.basiclineformatter.instance )

建议:实际取消HTTP请求的一个地方可以在进度对话框的OnCancel侦听器中,而不是Aynctask的OnCancelled()回调方法.

.

其他推荐答案

RestClient对象您使用的对象不会公开任何interrupt() DefaultHttpClient的方法(这是完成大部分工作的背词对象).没问题 - 首先,Defaulthttpclient似乎没有任何中断或流产的功能.

所以,您的左左侧操作在client.Execute()上.

您拥有解决方案的一半 - 将阻止操作放入线程中.您的体系结构掉落的位置 - 使用线程/侦听器设置,该设置不会为您提供很多摆动的空间.

尝试将匿名Thread切换到AsyncTask.这不会解决您client.Execute()的问题,但会让您丢弃侦听器(用onProgressUpdate()或onPostExecute()代替它).

这将允许您调用task.cancel(),向不再需要的任务发出信号.这将使您能够重新分配新的异步性,孤儿将被取消的任务重新分配,然后将孤立线程迅速完成,因为它的其余申请随之而来的是悄悄地死亡.

>

.

((在不相关的注释中," execute()"是一种方法,不应大写)

)

本文地址:https://www.itbaoku.cn/post/102678.html

问题描述

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.

推荐答案

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.

其他推荐答案

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