Cumulations Logo

 

Progress status when uploading file using retrofit

Retrofit 1

As we know Retrofit 1 uses TypedFile class to upload the file to the server. Actual problem arises when the user has to upload large files and you want to show update progress. In this case, you cannot simply show dialogue window and tell a user to wait, this will lead to a bad UX where a user is not satisfied. To avoid slow processing you can use this method and fasten up your task as you are uploading a file to the server so you know how much bites you have written to a socket and total file size hence we can determine percentage completion and can give better UX.

Retrofit provides class TypedFile we can subclass it and get to know file size and how much we have written in a buffer. Override writeTo function and do calculations

@Override
    public void writeTo(OutputStream out) throws IOException {
        byte[] buffer = new byte[BUFFER_SIZE];
        FileInputStream in = new FileInputStream(super.file());
        long readFile = 0;
        try {
            int read;
            while ((read = in.read(buffer)) != -1) {
                readFile += read;
                out.write(buffer, 0, read);
                int percentage = (int) ((readFile / (float) totalSize) * 100);

	//use interface for updating activity
                this.listener.fileUpdatingStatus(percentage);
            }

        } finally {

            in.close();
        }
    }

 

Retrofit 2

As Retrofit 2 doesn't use TypedFile so you can use OkHttp’s RequestBody class to find how much percentage we have written.

Step 1-Subclass RquestBody and override writeTo function.
Step 2-read file length and how much we wrote based on this calculate a percentage.
Step 3-Post it to UI.

@Override
    public void writeTo(BufferedSink sink) throws IOException {
        long fileLength = mFile.length();
        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        FileInputStream in = new FileInputStream(mFile);
        long uploaded = 0;

        try {
            int read;
            while ((read = in.read(buffer)) != -1) {
                uploaded += read;
                sink.write(buffer, 0, read);
		int percentage = (int) (( uploaded / (float) totalSize) * 100);

	//use interface for updating activity
                this.listener.fileUpdatingStatus(percentage);

            }

        } finally {
            in.close();
        }
    }

 

Click here to read about Mock API response in Retrofit using custom clients