【问题标题】:How to stop HttpURLConnection connect on Android如何在 Android 上停止 HttpURLConnection 连接
【发布时间】:2012-09-05 05:14:23
【问题描述】:

我使用 AsyncTask 连接 URLPath,如下代码所示。

@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) {
            //how to stop connect
        }
    });
    new Connecting().execute();
}


class Connecting extends AsyncTask<String, String, String> {
    @Override
    protected void onPreExecute() {
            super.onPreExecute();
        //do something
    }

        @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);
        //access InputStream is
        }
}

连接可能会花费大量时间。
在连接时,我想设置按下 Bbutton btn 以停止连接。
如何在 setOnClickListener 方法中设置?

【问题讨论】:

  • 你能在点击按钮时调用connection.close吗?
  • 连接可以通过按钮点击操作。但是如何调用连接关闭。
  • 我认为有一个默认函数 close() 可用于 HttpURLconnection 对象

标签: android android-asynctask httpurlconnection


【解决方案1】:

将使用HttpURLConnection 的代码封装在Future 中,您可以随意取消。您也可以使用Future 的超时功能,因为HttpURLConnection 中的超时不可靠。

在您的网络课程中定义执行者和未来:

final ExecutorService executor = Executors.newCachedThreadPool(Executors.defaultThreadFactory());
Future<MyResult> future;

然后将您的网络代码包装在 Future 中,如下所示:

future = executor.submit(new Callable<MyResult>() {
    @Override
    public MyResult call() throws IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        try {
            // .. use the connection ...
        } finally {
            connection.disconnect();
        }
    }
});

MyResult result = future.get(TIMEOUT, TimeUnit.SECONDS);

当您想取消时,您可以从任何线程进行此调用:

future.cancel(true);

如果未来超时或被取消,连接任务可能会继续阻塞HttpURLConnection 方法,但您的应用程序不会被阻止。您仍应在连接上设置适当的超时,以加快线程和网络套接字的释放速度。

【讨论】:

  • 如果 HttpURLConnection 正在等待读取,这不起作用。我现在正在测试它,取消后线程永远不会消失。我创建了一个测试,其中目标服务器出现内存不足的情况,它可以接受连接但永远不会返回。上面的代码永远无法取消线程。
  • @D-Klotz 线程池线程应该保留以供以后重用。这是ExecutorService 的实现细节。重要的是Future.get 会立即超时并返回。
  • @EdwardBrey 抱歉,我的表述不正确。当我挂起这些线程时,它们仍在: SocketInputStream.socketRead0(FileDescriptor, byte[], int, int, int) line: not available [native method] 这是在 cancel(true);
  • @D-Klotz Future.cancel interrupts 连接任务。在其众多问题中,HttpURLConnection 似乎忽略了中断。幸运的是,只要你的应用只考虑 Future 是否已经完成(包括超时或被取消),它就可以忽略这个缓慢的任务,知道它最终会消失。
  • @EdwardBrey 我不确定忽略线程是多么明智,尤其是在流量很大的情况下。这些线程将至少存在两个小时(默认 tcp 超时)。我们真的要让线程数不受限制地增长吗?我已经确定真正的解决方案是将 HttpURLConnection 本身的 readTimeout 设置为适合连接的值。感谢您的回复。
【解决方案2】:

通过 (HttpURLConnection)url.openConnection() 保存 HttpURLConnection 响应;作为班级成员: HttpURLConnection mHttpURLConnection = (HttpURLConnection)url.openConnection();

在你调用 future.cancel(true); 之后然后打电话 mHttpURLConnection.disconnect()

所以网络请求会尽快结束

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多