Android
General

Retrofit File Update Progress

Khajan Pandey

17 Apr 2016

Retrofit File Update Progress

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