19
19
package com .loopj .android .http ;
20
20
21
21
import java .io .IOException ;
22
+ import java .net .ConnectException ;
22
23
23
24
import org .apache .http .HttpResponse ;
24
25
import org .apache .http .client .HttpClient ;
26
+ import org .apache .http .client .HttpRequestRetryHandler ;
25
27
import org .apache .http .client .methods .HttpUriRequest ;
28
+ import org .apache .http .impl .client .AbstractHttpClient ;
26
29
import org .apache .http .protocol .HttpContext ;
27
30
28
31
public class AsyncHttpRequest implements Runnable {
29
- private HttpClient client ;
32
+ private AbstractHttpClient client ;
30
33
private HttpContext context ;
31
34
private HttpUriRequest request ;
32
35
private AsyncHttpResponseHandler responseHandler ;
36
+ private int executionCount ;
33
37
34
- public AsyncHttpRequest (HttpClient client , HttpContext context , HttpUriRequest request , AsyncHttpResponseHandler responseHandler ) {
38
+ public AsyncHttpRequest (AbstractHttpClient client , HttpContext context , HttpUriRequest request , AsyncHttpResponseHandler responseHandler ) {
35
39
this .client = client ;
36
40
this .context = context ;
37
41
this .request = request ;
@@ -44,10 +48,10 @@ public void run() {
44
48
responseHandler .sendStartMessage ();
45
49
}
46
50
47
- HttpResponse response = client .execute (request , context );
51
+ makeRequestWithRetries ();
52
+
48
53
if (responseHandler != null ) {
49
54
responseHandler .sendFinishMessage ();
50
- responseHandler .sendResponseMessage (response );
51
55
}
52
56
} catch (IOException e ) {
53
57
if (responseHandler != null ) {
@@ -56,4 +60,39 @@ public void run() {
56
60
}
57
61
}
58
62
}
63
+
64
+ private void makeRequest () throws IOException {
65
+ HttpResponse response = client .execute (request , context );
66
+ if (responseHandler != null ) {
67
+ responseHandler .sendResponseMessage (response );
68
+ }
69
+ }
70
+
71
+ private void makeRequestWithRetries () throws ConnectException {
72
+ // This is an additional layer of retry logic lifted from droid-fu
73
+ // See: https://github.com/kaeppler/droid-fu/blob/master/src/main/java/com/github/droidfu/http/BetterHttpRequestBase.java
74
+ boolean retry = true ;
75
+ IOException cause = null ;
76
+ HttpRequestRetryHandler retryHandler = client .getHttpRequestRetryHandler ();
77
+ while (retry ) {
78
+ try {
79
+ makeRequest ();
80
+ return ;
81
+ } catch (IOException e ) {
82
+ cause = e ;
83
+ retry = retryHandler .retryRequest (cause , ++executionCount , context );
84
+ } catch (NullPointerException e ) {
85
+ // there's a bug in HttpClient 4.0.x that on some occasions causes
86
+ // DefaultRequestExecutor to throw an NPE, see
87
+ // http://code.google.com/p/android/issues/detail?id=5255
88
+ cause = new IOException ("NPE in HttpClient" + e .getMessage ());
89
+ retry = retryHandler .retryRequest (cause , ++executionCount , context );
90
+ }
91
+ }
92
+
93
+ // no retries left, crap out with exception
94
+ ConnectException ex = new ConnectException ();
95
+ ex .initCause (cause );
96
+ throw ex ;
97
+ }
59
98
}
0 commit comments