7.2 KiB
Services - Communication
How can an activity communicate with a service?
By sending one or more intents
- This is done by calling
onStartCommandmultiple times
How should the service communicate with the user?
This is done through notifications
How should the service communicate with the activity?
For example: sending an email or playing an MP3
For this we use binding
How does the service guarantee that work is completed?
By using life-cycles
Notifications
Notifications are intended to inform users about events from an application.
- Potentially a source of disruption.
- Caused by something in the background
- Require the user's attention
- Adversely affect task completion time (of the user)
- Impact the emotional & effective state of the user
Cross-Platform Principles
Avoid
- An app the user has never opened
- Messages that encourage the user to return to an app, but provide no value
- Operations that don't require user involvement, like syncing information
- Error states from which the app could recover without user interaction
- Personal/sensitive/confidential information
Aim To
- Create succinct, easy-to-read notifications that provide useful information
- Provide intuitive, beneficial actions
Actioned via
- Showing a status bar icon
- Appearing on the lock screen
- Playing a sound/vibration
- Peeking onto the current screen
Relationship to Services
- Notify the user that the service is operating / has done something
- Service does not have a UI
- The notification is an invitation for the user to return to the application
- This is because the original activity might not still be running
- Service does not have a UI
- Notifications are maintained by the service
- Can specify an activity to launch if the user taps on it via a
PendingIntent- 'return' to the activity that spawned the service
- A
PendingIntentitself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that even if the owning application's process has been killed, thePendingIntentitself will remain usable from other processes that have been given it.
- Can control the service via buttons in the notification
- Deliver Intents to the service (
startService/onStartCommand), this works because the service is a singleton object
- Deliver Intents to the service (
- Can specify an activity to launch if the user taps on it via a
Activity/Service Navigation and State
Ways back to the activity
- Via service hosted notification
- Via task manager
- Via launcher
Depending on the owning process, the activity might have been
- Destroyed
- Finished
The activity is ephemeral (lasting a short amount of time)
- Incorrect to store server state in activity instance state
- What has the service been doing in the meantime?
- Interrogate service to retrieve non-instance state
onCreate,onBind - Start or stop the service (is it still necessary/needed)
Service Lifecycle
Two ways of spawning a service
- Started (loosely coupled)
- Send an intent to explicitly start the service with
startService() - Will run/exist in the background indefinitely / kills itself
- Useful for consistently checking emails
- Does not return a result
- Explicitly stop the service with
stopService()
- Send an intent to explicitly start the service with
- Bound (tightly coupled)
- Bind to a service using
bindService() - Will run while activities are bound to it
- Provides a programmatic interface for activities to communicate with the service
- Bind to a service using
In both cases, if the service is not running, it will be created.
- Different responsibilities for the lifecycle
- If I start it, I have to stop it
- If the OS starts it, the OS stops it when it decides to
- Two conflated purposes
- Manage the service lifecycle
- Bind to the service for communication
- Only Bind = automatic lifecycle
- Only Start = manual lifecycle, intent communication
- Start and Bind = manual lifecycle, programmatic interface
Terminating Services
A service runs in the background indefinitely
- Even if the component that started it is destroyed / finished
Termination of service
- Self-termination (calling
stopSelf()) stopService()via an intent- System termination
- i.e. memory storage
Avoiding termination
- Foregrounding a service
- This is something the user should really know about or is aware of
- Is treated as important as a foreground activity,
startForeground()
- Background services are vulnerable
- In Android 8.0+ - background services can and will be stopped by the system, enforcing a Cron / job scheduling model.
A service runs in the background indefinitely
- Indefinitely = a few minutes
- Even if the component that started it is destroyed
onStartCommand()return value determines how the service should be continued if it is destroyed
START_NOT_STICKY
- After
onStartCommand()returns, do not recreate the service unless there are intents to deliver
START_STICKY
- Recreate the service and call
onStartCommand()again, but do not redeliver the last intent.
START_REDELIVER_INTENT
- Recreate the service and call
onStartCommand()again; deliver the last intent- Immediately resume the previous job, i.e. downloading a file
Foreground Services and Notifications
Foreground services perform operations that are noticeable to the user
- Foreground services are app processes that run in the background while the user is not directly interacting with the app.
- Android requires users to be made aware of this with a non-dismissible notification
- Because the user can't dismiss the notification, you should provide an action (button) for the user to stop the service.
Examples
- A music player app
- A notification will continually show song progress, play/pause, etc.
Communicating with Services
Bind to the service
- If not explicitly started, will be started by the OS
- Provide an interface for clients (Activities) to interact with a service
- Aims to be fast and stable
- Binder object asynchronously provides a reference to the service that we can call methods on
- via
ServiceConnection - Binder object forms the basis of the programmatic interface for activities.
- i.e. we can use this object to call methods on the service
- Asynchronous as we have to wait for the OS to create the service
- via
| Activity | Service |
|---|---|
| Component | Service |
| Service Connection | IBinder |
onServiceConnected() |
What this binder object allows us to do:
We can use ServiceConnection to call methods on the service and receive results.
Activity/Service Communication
- Extending the Binder class
- Return an interface via the
inBind()method - Only for a Service used by the same application
- Local services only
- Make method calls within the same JVM (Android runtime)
- Return an interface via the
- Who drives communication?
- Activity - regularly polls the service for information
- Service
- Maintain a list of callbacks using Binder objects to identify activity clients
- Enumerate and call each activity via a callback interface

