Google is committed to advancing racial equity for Black communities. See how.

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 Templates 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 ScreenManager.popTo(String) when it should pop all the way to the root screen in the stack.

Protected constructors

Screen(CarContext carContext)

Public methods

final void finish()

Removes this screen from the stack, which will move its lifecycle state down to Lifecycle.State.DESTROYED.

final CarContext getCarContext()

Returns the CarContext of the CarAppService.

final Lifecycle getLifecycle()

Returns this screen's lifecycle.

String getMarker()

Retrieves the marker that has been set for this screen, or null if one has not been set.

final ScreenManager getScreenManager()

Returns the ScreenManager to use for pushing/removing screens.

abstract Template getTemplate()

Returns the Template to present in the car screen.

final void invalidate()

Requests the current template to be invalidated, which eventually triggers a call to getTemplate() to get the new template to display.

void setMarker(String marker)

Updates the marker for this screen.

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

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

Screen

protected Screen (CarContext carContext)

Parameters
carContext CarContext

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:

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 5 Screen 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 a ListTemplate 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 a Screen 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
Certain Template 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)