Since you have to deal with loading, I would suggest that when executing entity.writeTo(os); Most of the time. Perhaps the first contact with the server takes some time (DNS resolution, SSL handshake, ...). The tokens you set for "real boot" do not match IMO.
Now it depends on your Multipart library, whether you can intercept writeTo . If it is smart and resource-efficient, it iterates in parts and passes the contents one by one to the output stream. If not, and the .build() operation creates a lot of fat byte[] , you can take this array, pass it to the server chunks and tell your user how many percent of the download has already been completed.
In terms of resources, I would rather not know what is happening. But if feedback is important, and if the films are only a few megabytes in size, you can first transfer the Multipart-Entity object to ByteArrayOutputStream , and then write small fragments of the created byte array to the server, notifying the user about the progress. The following code is not verified and not verified (you can see it as pseudocode):
ByteArrayOutputStream baos = new ByteArrayOutputStream(); entity.writeTo(baos); baos.close(); byte[] payload = baos.toByteArray(); baos = null; OutputStream os = conn.getOutputStream(); int totalSize = payload.length; int bytesTransferred = 0; int chunkSize = 2000; while (bytesTransferred < totalSize) { int nextChunkSize = totalSize - bytesTransferred; if (nextChunkSize > chunkSize) { nextChunkSize = chunkSize; } os.write(payload, bytesTransferred, nextChunkSize);
A more elegant way would be to write an OutputStream hook that records progress and delegates real write operations to the underlying "real" OutputStream.
Edit
@whizzzkey wrote:
I re-checked it many times - entity.writeTo(os) DOES NOT conn.getResponseCode() load, it does conn.getResponseCode() or conn.getInputStream()
It is now clear. HttpURLConnection buffers your loaded data because it does not know the length of the content. You set the "Content-length" header, but obviously this is ignored by the HUC. You have to call
conn.setFixedLengthStreamingMode(entity.getContentLength());
Then you better remove the call to conn.setRequestProperty("Content-length", entity.getContentLength() + "");
In this case, the HUC can write headers, and entity.writeTo(os) can actually send data to the server. Otherwise, buffered data is sent when the HUC knows how many bytes will be transmitted. Thus, actually getInputStream() tells the HUC that you are done, but before you actually read the answer, all the data collected must be sent to the server.
I would not recommend changing the code, but for those of you who do not know the exact size of the transmitted data (in bytes, not in characters !!), you can tell HUC that it should transfer the data to pieces without setting the exact length of the content:
conn.setChunkedStreamingMode(-1);