5

場合によっては、長いポーリング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();
        }
    }
}

これは私が最初に開始する方法であり、次に(2番目の遅延の後)リクエストをキャンセルしようとします:

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();
    }
}

つまり、本質的には

  1. 読み取りタイムアウトが1分のgetリクエストでHttpUrlConnectionを開始します
  2. それから1秒後、私は以前のリクエストをキャンセルしようとします
  3. 期待される結果は、connection.disconnect()を呼び出すときに接続がIOExceptionをスローすることです。

そして、これはまさに、さまざまなエミュレーター(2.2〜4.0.3)、Motorola Atrix(2.3.7)、Samsung Note(4.0.1)で発生することです。ただし、2.2を実行している一部のHTCデバイスでは、接続を明示的に終了したにもかかわらず、リクエストは存続し、レスポンスを受信します。これをHTCDesireとHTCGildfireで確認しました。

何が起きてる?2.2以降を実行しているすべてのデバイスでこのようなリクエストを安全にキャンセルするにはどうすればよいですか?

自分で試乗したい場合は、コード全体をここで入手できます:https ://gist.github.com/3306225

4

2 に答える 2

4

何が起きてる?

これは以前のAndroidリリース(Froyo 2.2)の既知のバグであり、ソートでは、ソケットを他のスレッドによって非同期的に閉じることができず、Gingerbread2.3で修正されています。

問題11705:HttpURLConnectionを使用してHTTP接続を閉じることができません

2.2以降を実行しているすべてのデバイスでこのようなリクエストを安全にキャンセルするにはどうすればよいですか?

そのリンクのプロジェクトメンバーからのコメント:

現在のリリースで機能するこれの最良の近似は、HTTP接続で読み取りおよび接続タイムアウトを設定することです。

お役に立てば幸いです。

于 2012-08-13T03:41:38.750 に答える
0

実際には、androidで提供されているデフォルトの代わりに、ApacheHttpClientlibを使用することをお勧めします。

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();
于 2012-08-17T08:55:06.890 に答える