executifs
executifs

Reputation: 1178

What is the proper way to communicate between an Activity and a BroadcastReceiver?

I have a BroadcastReceiver which listens to system intents such as Intent.ACTION_PACKAGE_ADDED. When it receives one, the Activity needs to refresh its the data it presents. Of course, the Activity may not have focus, or may not even be running when this happens. What is the proper way to "leave a message" for the next time the Activity gains focus?

I thought of storing a boolean in the SharedPreferences, but something tells me this is not the right way to go.

Upvotes: 1

Views: 76

Answers (3)

CommonsWare
CommonsWare

Reputation: 1006744

What is the proper way to "leave a message" for the next time the Activity gains focus?

IMHO, you have four separate issues here:

Issue #1: How does the BroadcastReceiver tell a running Activity that an event occurred that may be of interest?

Solution: Use an event bus (LocalBroadcastManager, greenrobot's EventBus, Square's Otto), and post a package-added event from the receiver on the bus. Your activity can be registered for events from the bus while it is in the foreground, and it can update its view on the data when your event is received.

Issue #2: How does the BroadcastReceiver update the model data in the SQLite database when the broadcast occurs?

Solution: Delegate this, plus the receiver's side of the event bus logic, to an IntentService, as you need a background thread to do the database I/O. Post the event on the bus when the work is completed.

Issue #3: So, what happens if my activity is not in the foreground at the time the event goes out, but the activity exists (i.e., is in the background)?

Solution: Either reload your data in onResume() or use some sort of a "sticky" event with the bus. LocalBroadcastManager does not offer that, but greenrobot's EventBus has the notion of sticky events, and Square's Otto has a related @Producer construct.

Issue #4: What happens if I do not have an activity instance at all? For example, the package is added when my process is not running, so Android forks a process for me and invokes my receiver, but I have no UI code at all in my process right now?

Solution: Do nothing special. Your existing "load-the-data" logic will handle this case.

Upvotes: 4

Sandeep Shabd
Sandeep Shabd

Reputation: 721

One simple solution can be a static variable flag in Broadcastreceiver. Once receiver receives intent, make flag=true.

Activity when gains focus can look at this static variable and can refresh data accordingly and turn this static flag to false.

Upvotes: 2

droidpl
droidpl

Reputation: 5892

It depends of what you are trying to do when the Intent is received. If you only want to refresh the content, the the proper way is to use the onResume and onStopto attach the broadcast receiver listener. This will only work while the activity is on the foreground, so every time the user enters the activity again you need to reload the list to avoid the case that this intent arrived while not in foreground.

Another way to proceed if you want to listen it while you are not showing your UI is to create a Service that listens to this Intent with the BroadcastReceiver. Again it depends of the moments you need to receive this event.

To sum up:

  • For foreground UI: onResume to attach and onPause to detach.
  • For background: use a Service

Upvotes: 0

Related Questions