在某些情况下,我需要断开来自客户端的长轮询http请求。我对服务器进行的 HttpUrlConnection 的相关部分如下(下面的所有代码都在线程的 run() 方法中):
try {
URL url = new URL(requestURL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setConnectTimeout(5 * 1000);
connection.setReadTimeout(60 * 1000);
connection.setRequestMethod("GET");
// read the output from the server
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line + "\n");
}
Log.d(TAG, stringBuilder);
} catch (IOException ioe) {
Log.e(TAG, ioe);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
这就是我首先发起的方式,然后(第二次延迟后)尝试取消请求:
pollThread = new PollThread();
pollThread.start();
Log.d(TAG, "pollThread started");
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
pollThread.cancelRequest();
Log.d(TAG, "pollThread presumably cancelled");
}
}, 1000);
这就是 cancelRequest() 方法的样子:
public void cancelRequest() {
if (connection != null) {
connection.disconnect();
}
}
所以本质上,
这正是在各种模拟器 (2.2 - 4.0.3)、摩托罗拉 Atrix (2.3.7) 和三星 Note (4.0.1) 上发生的情况。但在某些运行 2.2 的 HTC 设备上,尽管我明确终止了连接,请求仍将保持活动状态并收到响应。我用 HTC Desire 和 HTC Wildfire 验证了这一点。
这是怎么回事?如何在运行 2.2+ 的所有设备上安全地取消此类请求?
为方便起见,如果您想亲自试驾,可以在此处获取完整代码:https://gist.github.com/3306225
这是早期 Android 版本(Froyo 2.2)中的一个已知错误,在某种程度上,套接字无法由其他线程异步关闭,并且已在 Gingerbread 2.3 中修复:
问题 11705:无法使用 HttpURLConnection 关闭 HTTP 连接
该链接中项目成员的评论:
在当前版本中有效的最佳近似方法是在 HTTP 连接上设置读取和连接超时。
希望有帮助。
实际上,我建议您使用 Apache HttpClient lib,而不是 android 提供的默认库。
您可以从以下位置下载:http://code.google.com/p/httpclientandroidlib/
如果你想“一路走下去”,你还可以使用“配置了合理的默认设置和注册 Android 方案”的 AndroidHttpClient,并且还可以支持 cookie。你可以从这里下载(我不记得什么时候找到原来的了...)
这就是你如何使用“Get”调用,我想你可以弄清楚剩下的事情:
InputStream isResponse = null;
HttpGet httpget = new HttpGet(strUrl);
HttpResponse response = getHttpClient().execute(httpget);
HttpEntity entity = response.getEntity();
isResponse = entity.getContent();
responseBody = convertStreamToString(isResponse);
和
/**
* @return the mClient
*/
protected AndroidHttpClient getHttpClient() {
if (mClient == null)
mClient = AndroidHttpClient.newInstance(mCookieStore);
return mClient;
}
关闭连接:
getHttpClient().close();
* @return the mClient
*/
protected AndroidHttpClient getHttpClient() {
if (mClient == null)
mClient = AndroidHttpClient.newInstance(mCookieStore);
return mClient;
}
getHttpClient().close();