Files
notes/docs/lectures/mdp/06_communication.md
T

7.2 KiB

Services - Communication

How can an activity communicate with a service?

By sending one or more intents

  • This is done by calling onStartCommand multiple 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
  • 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 PendingIntent itself 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, the PendingIntent itself 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

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()
  • 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

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

img

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

img

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)
  • 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