1

私のサービスの背景: LocationListener を実装し、LocationManager インスタンス (locMananager) で更新を登録します。

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ますか?

finallyInputSTream が閉じられたブロックを追加しました。ただし、オンデマンドで問題を発生させるのは難しいため (定期的に発生するわけではありません)、ストリームを閉じても問題が解決するかどうかは確認できません。

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 に答える