0

接続またはソケットがタイムアウトした場合は、 andを使用HttpClientして再試行します。HttpRequestRetryHandlerそのため、接続をオフにして、呼び出さHttpRequestRetryHandlerれることを期待して API を呼び出します。しかし、それは呼び出されません。メソッドに入ることすらありません。

コード :

HttpClient client = new DefaultHttpClient();
client.getParams().setIntParameter(
HttpConnectionParams.CONNECTION_TIMEOUT,
            CONNECTION_TIMEOUT * 1000);
client.getParams().setIntParameter(HttpConnectionParams.SO_TIMEOUT,
            SOCKET_TIMEOUT * 1000);

// Retry handler which handles request retry
HttpRequestRetryHandler requestRetryHandler = new HttpRequestRetryHandler() {

    @Override
    public boolean retryRequest(IOException exception,
                int executionCount, HttpContext context) {

        if ((exception instanceof ConnectTimeoutException || exception instanceof SocketTimeoutException)
                    && executionCount <= MAX_TRIES) {

            Log.d(TAG, "Retrying connection.");
            return true;

        } 

        return false;
    }
};

((AbstractHttpClient) client)
            .setHttpRequestRetryHandler(requestRetryHandler);

しかし、同時にConnectTimeoutException、以下に示すようにキャッチしようとすると、実行は のキャッチ ブロックに入りConnectTimeoutExceptionます。

try {

    // Making API request

} catch (ConnectTimeoutException ce) {

    // Execution enters here
    ce.printStackTrace();
}

私の avd は、android バージョンのジェリービーンで動作します。

コードに何か問題がありますか?

ConnectTimeoutException トレースを出力するときの Logcat :

ここに画像の説明を入力

4

3 に答える 3

2

私は同じ問題を抱えていたので、解決策を共有したいと思います(私のために働いた)。

一般的に使用されている多くの HTTP サーバーは、システム リソースを節約するために、一定期間非アクティブになった後に永続的な接続をドロップするように構成されています。HttpClient 接続のキープアライブ戦略を参照してください。

サーバーが接続を切断した場合、HttpRequestRetryHandler は再試行する機会がありません (その仕事をするため)。

だから私はこの方法で解決しました:

  1. カスタム接続キープアライブ戦略を実装

    mHttpClient.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
        // Honor 'keep-alive' header
        HeaderElementIterator it = new BasicHeaderElementIterator(
            response.headerIterator(HTTP.CONN_KEEP_ALIVE));
        while (it.hasNext()) {
            HeaderElement he = it.nextElement();
            String param = he.getName(); 
            String value = he.getValue();
            if (value != null && param.equalsIgnoreCase("timeout")) {
                try { return Long.parseLong(value) * 1000; } 
                catch(NumberFormatException ignore) {  }
            }
        }
    
        ......
    
        //.Keep Alive for 30 secs
        return 30 * 1000;
      }
    });
    
  2. 次に、カスタム再試行ハンドラーを実装しました。

    HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
    
        public boolean retryRequest(IOException exception, 
                                    int executionCount, 
                                    HttpContext context) {
            // retry a max of 5 times
            if (executionCount >= 5) return false;
    
            if (exception instanceof NoHttpResponseException) {
                // Retry if the server dropped connection on us
                return true;
            }
    
            //.TODO your custom logic...
    
            Boolean b = (Boolean)
                context.getAttribute(ExecutionContext.HTTP_REQ_SENT);
            boolean sent = (b != null && b.booleanValue());   
            if (!sent) {
                // Retry if the request has not been sent fully or
                // if it's OK to retry methods that have been sent
                return true;
            }
    
            // otherwise do not retry
            return false;
        }
    };
    
    mHttpClient.setHttpRequestRetryHandler(retryHandler); 
    
于 2013-07-05T10:31:01.293 に答える