如何在Android上停止HttpURLConnection的连接

11 浏览
0 Comments

如何在Android上停止HttpURLConnection的连接

我使用AsyncTask连接URLPath,代码如下:\n

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.left_list);
    Button btn = (Button)findViewById(resid);
    btn.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            //如何停止连接
        }
    });
    new Connecting().execute();
}
class Connecting extends AsyncTask {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //做一些操作
    }
    @Override
    protected String doInBackground(String... aurl) {
        try {
            URL url = new URL(URLPath);
            connection = (HttpURLConnection)url.openConnection();
            connection.setConnectTimeout(30000);
            connection.setReadTimeout(30000);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.connect();
            is = connection.getInputStream();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    @Override
    protected void onPostExecute(String unused) {
        super.onPostExecute(unused);
        //访问InputStream is
    }
}

\n连接可能花费很长时间。
\n在连接期间,我想要设置按钮btn按下以停止连接。
\n我该如何在setOnClickListener方法中设置?

0
0 Comments

问题原因:在Android中停止HttpURLConnection连接的原因是为了尽快结束网络请求,以节省资源。

解决方法:将HttpURLConnection的连接保存为类成员变量,并在调用future.cancel(true)后调用mHttpURLConnection.disconnect()来停止连接。

代码示例:

// 将HttpURLConnection连接保存为类成员变量
HttpURLConnection mHttpURLConnection = (HttpURLConnection)url.openConnection();
// 调用future.cancel(true)后调用mHttpURLConnection.disconnect()来停止连接
mHttpURLConnection.disconnect();

通过以上方法可以实现在Android中停止HttpURLConnection连接的目的。

0
0 Comments

问题的原因是:使用HttpURLConnection时,其连接超时并不可靠,无法准确控制连接的停止。

解决方法是:将使用HttpURLConnection的代码包装在一个Future中,通过取消Future来停止连接。同时,可以利用Future的超时特性来设置连接的超时时间。此外,还需在连接上设置适当的超时时间,以加快线程和网络套接字的释放。

以下是解决方法的具体实现代码:

final ExecutorService executor = Executors.newCachedThreadPool(Executors.defaultThreadFactory());
Future future;
future = executor.submit(new Callable() {
    public MyResult call() throws IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        try {
            // .. 使用连接 ...
        } finally {
            connection.disconnect();
        }
    }
});
MyResult result = future.get(TIMEOUT, TimeUnit.SECONDS);

当需要取消连接时,可以从任何线程中调用以下代码:

future.cancel(true);

如果Future超时或被取消,连接任务可能会继续阻塞在HttpURLConnection方法上,但是应用程序不会受到阻碍。为了加快线程和网络套接字的释放,仍然应在连接上设置适当的超时时间。

然而,如果HttpURLConnection在等待读取时,上述方法无法生效。在这种情况下,可以考虑设置连接的readTimeout属性,以适应连接的情况。

需要注意的是,Future并不是连接超时的替代品,而是一种补充。在HttpURLConnection中设置的超时时间并不能涵盖所有情况,它可能会进入阻塞状态,超过你设置的最长超时时间。

以下是一些关于该的问题:

- 线程池中的线程会保留以供后续重用,这是ExecutorService的实现细节。重要的是,Future.get会及时超时并返回。

- Future.cancel中断连接任务。不过,HttpURLConnection似乎会忽略中断。但幸运的是,只要应用程序只考虑Future是否已完成(包括超时或被取消),它可以忽略未完成的任务,知道它最终会被清除。

- 忽略线程可能不是明智的,特别是在高流量情况下。这些线程至少会保留两个小时(默认的TCP超时时间)。我们真的想要允许线程数量不受限制地增长吗?我已经确定真正的解决方案是将HttpURLConnection本身的readTimeout设置为适当的值。谢谢你的回答。

- Future并不是连接超时的替代品,而是一种补充。我更新了我的答案来澄清这一点。不幸的是,HttpURLConnection中的超时时间并不能涵盖所有情况。它可能会进入阻塞状态,超过你设置的最长超时时间。

- 线程不会停止是因为读/写操作不响应中断。它们只有在读/写超时时才会停止。据我所知,你无法配置写操作的超时时间。

文章整理完毕。

0