1

I'm trying to figure out proper/recommended approaches avoiding missed events from a long-running service during a configuration change. For example, I need to avoid a situation where an Activity misses a task completion event when the device is rotated, causing a progress spinner to stay visible.

I'm currently handling this by creating a view-less retained Fragment, named EventCollector, that contains a BroadcastReceiver which receives broadcasts from the service. An Activity, or any other class that wants to receive these events, implements EventCollectorListener and calls EventCollector.attachListener(TAG, this) to register and EventCollector.detachListener(TAG) to unregister for receiving events. When detached, events are stored in a queue until attachListener() is called again. (Implementation is available at [1] and example at [2]).

A normal flow of events would be something like the following:

  1. Activity is started.
  2. Activity attaches itself by calling EventCollector.attachListener() in onResume().
  3. Activity handles events from the onEventReceived() method of the EventCollectorListener interface.
  4. User rotates device.
  5. Activity detaches itself by calling EventCollector.detachListener() in onPause() before it gets destroyed.
  6. Events received during this time from the service are queued in the EventCollector instance.
  7. Activity is recreated and calls EventCollector.attachListener() in onResume() again, at which point, all queued events are sent.

This has some disadvantages, like how every single event between onPause() and onResume() is cached. If my service is extracting a zip archive, for example, there is no point keeping progress events for 1%, 2%, etc, if the process is already 80% done. Also, if the Activity is purposely destroyed (eg. back button), events will continue piling up in the queue.

I feel like my solution is very hacky and it seems like I'm working against the way Android is supposed to work. I've not seen anybody use a solution like this and I assume this is a fairly common use case, so are there better ways to avoid missed events from services? Am I totally wrong in my approach of handling long-running tasks by using IntentServices and intents/broadcasts for communication? Should I be using a bound service instead and if so, how would the general structure look like?

I don't mind making drastic changes to implement a better solution.

Thanks in advance! Any feedback is appreciated.


References:

  1. https://github.com/chenxiaolong/DualBootPatcher/blob/47f13965adf4793fea784b736475fa912f7c8d27/Android_GUI/src/com/github/chenxiaolong/dualbootpatcher/EventCollector.java
  2. https://github.com/chenxiaolong/DualBootPatcher/blob/47f13965adf4793fea784b736475fa912f7c8d27/Android_GUI/src/com/github/chenxiaolong/dualbootpatcher/switcher/SwitcherEventCollector.java
Andrew Gunnerson
  • 638
  • 1
  • 8
  • 17

0 Answers0