Search code examples
androidfile-uploadbroadcastreceiverintentservicelocalbroadcastmanager

Android IntentService/Service to request/send data to web service and getting the progress to UI


On Android basically, I am trying to upload/download data from a web service and have a progress bar that should be rendered showing the progress percentage.

Following is the approach that I implemented along with the reason for considering them:

  1. Chose IntentService to run in background: As per the link I could not use bound service as it will destroy when the binded Activity/Fragment is destroyed. Hence the selection of IntentService over Service. Move over it would be one time and intent service works on a worker thread so it is much better.
  2. Broadcast to receive updates: Implementation of LocalBroadcastManager to update the progress bar UI by registering it to listen to the broadcast received from the IntentService described above.

However with this approach, the following issue needs to be addressed:

Sequence of broadcasts is not maintained. The broadcast carries the percentage of progress of the upload/download. But since the sequence is not maintained, there are chances that I receive stale updates (eg: I may receive 30% after 40%). I also tried using sendBroadcastSync method of the LocalBroadcastManager but it doesn't work consistently (I am not very sure on this). Hence I tried to implement Messenger via Handler however I got to know that the approach will not be able to reconnect to the on going upload/download once the UI is re-created (Activitiy/Fragment is destroyed and created). Basically the reference to the Handler is lost along with the previous activity/fragment and hence the messages are not delivered to the UI for update.

I have been trying to get my way about since a while but I am not able to get it done. Your words of wisdom will be very helpful.


Solution

  • I would go about the problem a bit differently, as ordering of messages may be a problem with a variety of message solutions.

    The fact that you get the 40% event after the 30% event is not really a problem. What is a problem is if you update the UI to reflect 30%.

    Have each event (each Intent when using LocalBroadcastManager as your event bus) contain a timestamp along with the percentage-complete. Track in your UI the last-seen event timestamp. If you get an event that is older than your last-seen event timestamp, ignore that event.

    If you are sure that your percentage is monotonically increasing — in other words, that there is no legitimate scenario in which you might drop from 40% to 30% complete — you could skip the timestamp and just only apply new percentages that are higher than your currently-showing percentage.