Skip to content

Commit 256ec94

Browse files
committed
Implement progress notifications for file uploads.
Overwrite AsyncHttpResponseHandler.onProgress to get progress notifications. The implementation forwards a reference to AsyncHttpResponseHandler to SimpleMultipartEntity. SimpleMultipartEntity than fires the progress messages every CHUNKSIZE=65536 bytes in writeTo().
1 parent 6beb228 commit 256ec94

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

src/com/loopj/android/http/AsyncHttpClient.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ public void post(String url, RequestParams params, AsyncHttpResponseHandler resp
389389
* @param responseHandler the response handler instance that should handle the response.
390390
*/
391391
public void post(Context context, String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
392-
post(context, url, paramsToEntity(params), null, responseHandler);
392+
post(context, url, paramsToEntity(params, responseHandler), null, responseHandler);
393393
}
394394

395395
/**
@@ -420,7 +420,7 @@ public void post(Context context, String url, HttpEntity entity, String contentT
420420
public void post(Context context, String url, Header[] headers, RequestParams params, String contentType,
421421
AsyncHttpResponseHandler responseHandler) {
422422
HttpEntityEnclosingRequestBase request = new HttpPost(url);
423-
if(params != null) request.setEntity(paramsToEntity(params));
423+
if(params != null) request.setEntity(paramsToEntity(params, responseHandler));
424424
if(headers != null) request.setHeaders(headers);
425425
sendRequest(httpClient, httpContext, request, contentType,
426426
responseHandler, context);
@@ -479,7 +479,7 @@ public void put(String url, RequestParams params, AsyncHttpResponseHandler respo
479479
* @param responseHandler the response handler instance that should handle the response.
480480
*/
481481
public void put(Context context, String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
482-
put(context, url, paramsToEntity(params), null, responseHandler);
482+
put(context, url, paramsToEntity(params, responseHandler), null, responseHandler);
483483
}
484484

485485
/**
@@ -584,11 +584,11 @@ public static String getUrlWithQueryString(String url, RequestParams params) {
584584
return url;
585585
}
586586

587-
private HttpEntity paramsToEntity(RequestParams params) {
587+
private HttpEntity paramsToEntity(RequestParams params, AsyncHttpResponseHandler responseHandler) {
588588
HttpEntity entity = null;
589589

590590
if(params != null) {
591-
entity = params.getEntity();
591+
entity = params.getEntity(responseHandler);
592592
}
593593

594594
return entity;

src/com/loopj/android/http/AsyncHttpResponseHandler.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public class AsyncHttpResponseHandler {
7474
protected static final int FAILURE_MESSAGE = 1;
7575
protected static final int START_MESSAGE = 2;
7676
protected static final int FINISH_MESSAGE = 3;
77+
protected static final int PROGRESS_MESSAGE = 4;
7778

7879
private Handler handler;
7980

@@ -151,6 +152,10 @@ public void onFailure(Throwable error, String content) {
151152
onFailure(error);
152153
}
153154

155+
/**
156+
* Fired when the request progress, override to handle in your own code
157+
*/
158+
public void onProgress(int position, int length) {}
154159

155160
//
156161
// Pre-processing of messages (executes in background threadpool thread)
@@ -176,6 +181,9 @@ protected void sendFinishMessage() {
176181
sendMessage(obtainMessage(FINISH_MESSAGE, null));
177182
}
178183

184+
protected void sendProgressMessage(int position, int length) {
185+
sendMessage(obtainMessage(PROGRESS_MESSAGE, new Object[]{position, length}));
186+
}
179187

180188
//
181189
// Pre-processing of messages (in original calling thread, typically the UI thread)
@@ -210,6 +218,10 @@ protected void handleMessage(Message msg) {
210218
case FINISH_MESSAGE:
211219
onFinish();
212220
break;
221+
case PROGRESS_MESSAGE:
222+
response = (Object[])msg.obj;
223+
onProgress(((Integer)response[0]).intValue(), ((Integer)response[1]).intValue());
224+
break;
213225
}
214226
}
215227

src/com/loopj/android/http/RequestParams.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,12 +224,13 @@ public String toString() {
224224

225225
/**
226226
* Returns an HttpEntity containing all request parameters
227+
* @param progressHandler
227228
*/
228-
public HttpEntity getEntity() {
229+
public HttpEntity getEntity(AsyncHttpResponseHandler progressHandler) {
229230
HttpEntity entity = null;
230231

231232
if(!fileParams.isEmpty()) {
232-
SimpleMultipartEntity multipartEntity = new SimpleMultipartEntity();
233+
SimpleMultipartEntity multipartEntity = new SimpleMultipartEntity(progressHandler);
233234

234235
// Add string params
235236
for(ConcurrentHashMap.Entry<String, String> entry : urlParams.entrySet()) {

src/com/loopj/android/http/SimpleMultipartEntity.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,25 @@
4040
class SimpleMultipartEntity implements HttpEntity {
4141
private final static char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
4242

43+
private final static int CHUNKSIZE = 65536;
44+
4345
private String boundary = null;
4446

47+
private AsyncHttpResponseHandler progressHandler;
48+
4549
ByteArrayOutputStream out = new ByteArrayOutputStream();
4650
boolean isSetLast = false;
4751
boolean isSetFirst = false;
4852

49-
public SimpleMultipartEntity() {
53+
54+
public SimpleMultipartEntity(AsyncHttpResponseHandler progressHandler) {
5055
final StringBuffer buf = new StringBuffer();
5156
final Random rand = new Random();
5257
for (int i = 0; i < 30; i++) {
5358
buf.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
5459
}
5560
this.boundary = buf.toString();
56-
61+
this.progressHandler = progressHandler;
5762
}
5863

5964
public void writeFirstBoundaryIfNeeds(){
@@ -160,7 +165,13 @@ public boolean isStreaming() {
160165

161166
@Override
162167
public void writeTo(final OutputStream outstream) throws IOException {
163-
outstream.write(out.toByteArray());
168+
byte[] ba = out.toByteArray();
169+
for (int pos = 0; pos < ba.length; pos += CHUNKSIZE) {
170+
progressHandler.sendProgressMessage(pos, ba.length);
171+
outstream.write(ba, pos, pos + CHUNKSIZE <= ba.length ? CHUNKSIZE : ba.length - pos);
172+
}
173+
progressHandler.sendProgressMessage(ba.length, ba.length);
174+
// outstream.write(out.toByteArray());
164175
}
165176

166177
@Override

0 commit comments

Comments
 (0)