Screen
public
abstract
class
Screen
extends Object
implements
LifecycleOwner
java.lang.Object | |
↳ | com.google.android.libraries.car.app.Screen |
A Screen has a Lifecycle
and provides the mechanism for the app to send Template
s
to display when the Screen is visible. Screen instances can also be pushed and popped to and from
a Screen stack, which ensures they adhere to the template flow restrictions (see getTemplate()
for more details on template flow).
The Screen class can be used to manage individual units of business logic within a car app. A
Screen is closely tied to the CarAppService
it is a part of, and cannot be used without
it. Though Screen defines its own lifecycle (see getLifecycle()
), that lifecycle is
dependent on its CarAppService
: if the car app service is stopped, no screens inside of
it can be started; when the car app service is destroyed, all screens will be destroyed.
Screen objects are not thread safe and all calls should be made from the same thread.
Summary
Constants | |
---|---|
String |
ROOT
A marker to use with |
Protected constructors | |
---|---|
Screen(CarContext carContext)
|
Public methods | |
---|---|
final
void
|
finish()
Removes this screen from the stack, which will move its lifecycle state down to |
final
CarContext
|
getCarContext()
Returns the |
final
Lifecycle
|
getLifecycle()
Returns this screen's lifecycle. |
String
|
getMarker()
Retrieves the |
final
ScreenManager
|
getScreenManager()
Returns the |
abstract
Template
|
getTemplate()
Returns the |
final
void
|
invalidate()
Requests the current template to be invalidated, which eventually triggers a call to |
void
|
setMarker(String marker)
Updates the marker for this screen. |
void
|
setResult(Object result)
Sets the |
Inherited methods | |
---|---|
Constants
ROOT
public static final String ROOT
A marker to use with ScreenManager.popTo(String)
when it should pop all the way to the root
screen in the stack.
Constant Value: "ROOT"
Protected constructors
Public methods
finish
public final void finish ()
Removes this screen from the stack, which will move its lifecycle state down to Lifecycle.State.DESTROYED
.
Call when your screen is done and should be removed from the stack.
If this screen is the only one in the stack, it will not be finished.
getCarContext
public final CarContext getCarContext ()
Returns the CarContext
of the CarAppService
.
Returns | |
---|---|
CarContext |
getLifecycle
public final Lifecycle getLifecycle ()
Returns this screen's lifecycle.
Here are some ways you can use a Screen's Lifecycle
:
- Observe its
Lifecycle
by callingLifecycle.addObserver(LifecycleObserver)
. You can use theLifecycleObserver
to take specific actions whenever the screen receives differentLifecycle.Event
s. - Use this Screen to observe
LiveData
s that may drive the backing data for your templates.
What each Lifecycle.Event
means for a screen:
Lifecycle.Event.ON_CREATE
- The screen is in the process of being pushed to the screen stack, it is valid, but
contents from it are not yet visible in the car screen. You should get a callback to
getTemplate()
at a point after this call. Lifecycle.Event.ON_START
- The template returned from this screen is visible in the car screen.
Lifecycle.Event.ON_RESUME
- The user can now interact with the template returned from this screen.
Lifecycle.Event.ON_PAUSE
- The user can no longer interact with this screen's template.
Lifecycle.Event.ON_STOP
- The template returned from this screen is no longer visible.
Lifecycle.Event.ON_DESTROY
- This screen is no longer valid and is removed from the screen stack.
Listeners that are added in Lifecycle.Event.ON_START
, should be removed in Lifecycle.Event.ON_STOP
.
Similarly, listeners that are added in Lifecycle.Event.ON_CREATE
should be removed in Lifecycle.Event.ON_DESTROY
.
Returns | |
---|---|
Lifecycle |
See also:
getMarker
public String getMarker ()
Retrieves the marker
that has been set for this screen, or null
if one has not
been set.
Returns | |
---|---|
String |
See also:
getScreenManager
public final ScreenManager getScreenManager ()
Returns the ScreenManager
to use for pushing/removing screens.
Returns | |
---|---|
ScreenManager |
getTemplate
public abstract Template getTemplate ()
Returns the Template
to present in the car screen.
This method is invoked whenever a new template is needed, for example, the first time the
screen is created, or when the UI is invalidated through a call to invalidate()
.
Throttling of UI updates
To minimize user distraction while driving, the host will throttle template updates to the car screen. When the app invalidates multiple times in a short period, the host will call this method for each call, but it may not update the actual car screen right away. This will ensure there are not excessive UI changes in a short period of time.For example, if the app sends the host two or more templates within a period of time shorter than the throttle period, only the last template will be displayed on the car screen.
Template Restrictions
The host limits the number of templates to display for a given task to a maximum of 5, of which the last template of the 5 must be one of the following types: If the 5 template quota is exhausted and the app attempts to send a new template, the host will display an error message to the user. Note that this limit applies to the number of templates, and not the number of screen instances in the stack. For example, if while in screen A an app sends 2 templates, and then pushes screen B, it can now send 3 more templates. Alternatively, if each screen is structured to send a single template, then the app can push 5Screen
instances onto the ScreenManager
stack.
There are special cases to these restrictions: template refreshes, back and reset operations.
Template Refreshes
Certain content updates are not counted towards the template limit. In general, as long as an app returns a template that is of the same type and contains the same main content as the previous template, the new template will not be counted against the quota. For example, updating the toggle state of a row in aListTemplate
does not count against the quota. See
the documentation of individual Template
classes to learn more about what types of
content updates can be considered a refresh.
Back Operations
To enable sub-flows within a task, the host detects when an app is popping aScreen
from the ScreenManager
's stack, and updates the remaining quota based on the number of
templates that the app is going backwards by.
For example, if while in screen A, the app sends 2 templates and then pushes screen B and sends 2 more templates, then the app has 1 quota remaining. If the app now pops back to screen A, the host will reset the quota to 3, because the app has gone backwards by 2 templates.
Note that when popping back to a Screen
, an app must send a Template
that is
of the same type as the one last sent by that screen. Sending any other template types would
cause an error. However, as long as the type remains the same during a back operation, an app
can freely modify the contents of the template without affecting the quota.
Reset Operations
CertainTemplate
classes have special semantics that signify the end of a task. For
example, the NavigationTemplate
is a template that is expected to stay on the screen and be refreshed with new turn-by-turn
instructions for the user’s consumption. Upon reaching one of these templates, the host will
reset the template quota, treating that template as if it is the first step of a new task, thus
allowing the app to begin a new task. See the documentation of individual Template
classes to see which ones trigger a reset on the host.
If the host receives an Intent
to start the car app from a
notification action or from the launcher, the quota will also be reset. This mechanism allows
an app to begin a new task flow from notifications, and it holds true even if an app is already
bound and in the foreground.
See CarAppExtender
for details on
notifications.
Returns | |
---|---|
Template |
invalidate
public final void invalidate ()
Requests the current template to be invalidated, which eventually triggers a call to getTemplate()
to get the new template to display.
If the current Lifecycle.State
of this screen is not at least Lifecycle.State.STARTED
, then a
call to this method will have no effect.
After the call to invalidate is made, subsequent calls have no effect until the new template
is returned by getTemplate()
.
To avoid race conditions with calls to getTemplate()
you should call this method with
the main thread.
Throws | |
---|---|
HostException |
if the remote call fails. |
setMarker
public void setMarker (String marker)
Updates the marker for this screen.
Set the marker
to null
to clear it.
This is used for setting a marker to where you can jump back to by calling ScreenManager.popTo(String)
.
Parameters | |
---|---|
marker |
String |
setResult
public void setResult (Object result)
Sets the result
that will be sent to the OnScreenResultCallback
that was given
when pushing this screen onto the stack using ScreenManager.pushForResult(Screen, OnScreenResultCallback)
.
Only the final result
set will be sent.
The result
will be propagated when this screen is being destroyed. This can be due
to being removed from the stack or explicitly calling finish()
.
Parameters | |
---|---|
result |
Object : the value to send to the OnScreenResultCallback that was given when
pushing this screen onto the stack using ScreenManager.pushForResult(Screen, OnScreenResultCallback)
|