1

我的服务的背景:它实现了 LocationListener 并在 LocationManager 实例 (locManager) 中注册更新:

manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);

在 onLocationChanged 方法中,它使用当前位置调用名为 recordTrace 的方法,然后调用 getHttpResponse 将位置坐标发送到服务器。后一种方法如下:

    public InputStream getHttpResponse(String url, ArrayList<NameValuePair> params, int timeout) throws Exception {
    DefaultHttpClient httpClient = new DefaultHttpClient();
    HttpParams httpParams = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(httpParams, timeout);
    httpClient.setParams(httpParams);
    HttpPost post = new HttpPost(url);
    if(params != null && !params.isEmpty()) {
        try {
            post.setEntity(new UrlEncodedFormEntity(params));
        } catch (UnsupportedEncodingException e) {
            Log.e(TAG, "HttpPost.setEntity Error: " + e.getMessage());
            lastError = "błąd HTTP";
        }
    }
    CookieStore store = new BasicCookieStore();
    if(localCookies != null && localCookies.size() > 0) {
        for(int i = 0; i < localCookies.size(); i++) {
            store.addCookie(localCookies.get(i));
        }
    }
    HttpContext context = new BasicHttpContext();
    context.setAttribute(ClientContext.COOKIE_STORE, store);
    HttpResponse response = null;
    HttpEntity entity = null;
    InputStream content = null;
    try {
        response = httpClient.execute(post, context);
        store = (CookieStore) context.getAttribute(ClientContext.COOKIE_STORE);
        List<Cookie> cookies = store.getCookies();
        if(cookies != null && cookies.size() > 0) {
            localCookies = new ArrayList<BasicClientCookie>();
            for(Cookie cookie : cookies) {
                localCookies.add((BasicClientCookie) cookie);
            }
        }
        entity = response.getEntity();
        content = entity.getContent();
        return content;
    } catch (ClientProtocolException e) {
        throw e;
    } catch (IOException e) {
        throw e;
    } catch (Exception e) {
        throw e;
    }
}

params 是带有准备好的数据的 NameValuePair,超时设置为 5000(5 秒)。ArrayList localCookies 保存成功登录之前保存的cookie(以保持会话)。

问题是:当我失去移动信号时(即当我去地铁时)并恢复它,我得到IOException,除非我重新启动手机,否则它是不可恢复的。

任何帮助,将不胜感激。我疯了,秃头了!

谢谢,彼得。

编辑 我做了一些研究。方法getHttpResponse调用后,我利用了它返回的InputStream,但毕竟没有关闭它。你觉得这可能是问题吗?这是否可能是操作员断开连接然后建立一个新连接,而我InputStream以某种方式“保持”以前的连接并产生数据传输问题?

我添加了一个finally块,现在 InputSTream 已关闭。但是,由于很难按需引起问题(它不会经常发生),我无法检查关闭流是否解决了它。

4

1 回答 1

1

经过几天的测试,我似乎找到了解决方案。调用 2 个方法可以解决问题:

  1. 关闭InputStream返回的httpResponse.getEntity()

  2. 通过执行关闭连接httpClient.getConnectionManager().shutdown()

完整请求和响应处理的代码片段:

String url = "www.someurl.com";
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("login", "mylogin"));
params.add(new BasicNameValuePair("password", "mypassword"));
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
try {
    httpPost.setEntity(new UrlEncodedFormEntity(params));
    HttpResponse httpResponse = httpClient.execute(httpPost);
    HttpEntity httpEntity = httpResponse.getEntity();
    InputStream content = httpEntity.getContent();
    /*
     * utilize content here...
     */
    content.close();    // here's the point
    httpClient.getConnectionManager().shutdown();   // the second important thing
}
catch (UnsupportedEncodingException e) {}
catch (ClientProtocolException e) {}
catch (IOException e) {}

我正在回答我自己的问题,因为我花了很多时间来搜索导致问题的原因,我认为我可以节省别人的时间。几天后,应用程序仍在工作并且不会中断连接。

问候,

彼得。

于 2012-11-20T13:43:47.750 回答