如何在Android上停止HttpURLConnection的连接
如何在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方法中设置?
问题原因:在Android中停止HttpURLConnection连接的原因是为了尽快结束网络请求,以节省资源。
解决方法:将HttpURLConnection的连接保存为类成员变量,并在调用future.cancel(true)后调用mHttpURLConnection.disconnect()来停止连接。
代码示例:
// 将HttpURLConnection连接保存为类成员变量 HttpURLConnection mHttpURLConnection = (HttpURLConnection)url.openConnection(); // 调用future.cancel(true)后调用mHttpURLConnection.disconnect()来停止连接 mHttpURLConnection.disconnect();
通过以上方法可以实现在Android中停止HttpURLConnection连接的目的。
问题的原因是:使用HttpURLConnection时,其连接超时并不可靠,无法准确控制连接的停止。
解决方法是:将使用HttpURLConnection的代码包装在一个Future中,通过取消Future来停止连接。同时,可以利用Future的超时特性来设置连接的超时时间。此外,还需在连接上设置适当的超时时间,以加快线程和网络套接字的释放。
以下是解决方法的具体实现代码:
final ExecutorService executor = Executors.newCachedThreadPool(Executors.defaultThreadFactory()); Futurefuture; 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中的超时时间并不能涵盖所有情况。它可能会进入阻塞状态,超过你设置的最长超时时间。
- 线程不会停止是因为读/写操作不响应中断。它们只有在读/写超时时才会停止。据我所知,你无法配置写操作的超时时间。
文章整理完毕。