Android: Uploading a photo in Cloudinary with progress callback in HttpURLConnection

China☆狼群 提交于 2019-12-01 04:16:20
aleksamarkoni

There is a problem in the use of flush() method and the time you call update callback().

As you can see from your code every time you read part of the picture, you write it to the output buffer, but that does not mean it's sent to the server, it might be buffered, and then later on write'n to the server.

You have two options, either call outputStream.flush() after every outputStream.write(), but that will kill the performance of the upload, because you would lose the benefits of buffering.

Or you could call your updateCallback() after the outputStream.flush() at the end of your method. Because after outputStream.flush() you are certain that the data is on the server, and that progress is over.

For more info about the flush see this thread What is the purpose of flush() in Java streams?

This is a shot in the dark because I have not tested on an Android environment, however I would recommend trying the following.

Instead of using a fixed length use setChunkedStreamingMode

//httpConn.setFixedLengthStreamingMode(filesize);
httpConn.setChunkedStreamingMode(4096); // or whatever size you see fit

doing this should trigger part of the request to get sent every time you send in 4096 bytes of data and essentially flushing out the internal buffer.


You could also try manually flushing the buffer after each write, this could slow down the file upload especially if you flush to often however it would likely fix your problem. You might end up playing with buffer sizes to find a sweet spot.

while ((bytesRead = inputStream.read(buffer)) != -1) {
    outputStream.write(buffer, 0, bytesRead);
    progress += bytesRead;
    /* int percentage = ((progress / filesize.intValue()) * 100);*/
    if (uploadingCallback != null) {
        uploadingCallback.uploadListener(progress);
    }
    // trigger the stream to write its data
    outputStream.flush();
 }

With either of these changes you would likely want to let the user choose to set their own buffer size instead of passing in the total file size. EG change your constructor to the following:

MultipartUtility(String requestURL, String charset, 
                 String boundary, Map<String, String> headers, int chunkSize)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!