# Screen

Artifact: [androidx.car.app:app](https://developer.android.com/jetpack/androidx/releases/car-app) [View Source](https://cs.android.com/search?q=file:androidx/car/app/Screen.java+class:androidx.car.app.Screen) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/car-app#1.0.0)

*** ** * ** ***


```
public abstract class Screen implements LifecycleOwner
```

<br />

*** ** * ** ***

A Screen has a `https://developer.android.com/reference/androidx/lifecycle/Lifecycle` and provides the mechanism for the app to send `https://developer.android.com/reference/androidx/car/app/model/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 `https://developer.android.com/reference/androidx/car/app/Screen#onGetTemplate()` 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 `https://developer.android.com/reference/androidx/car/app/CarAppService` it is a part of, and cannot be used without it. Though Screen defines its own lifecycle (see `https://developer.android.com/reference/androidx/car/app/Screen#getLifecycle()`), that lifecycle is dependent on its `https://developer.android.com/reference/androidx/car/app/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

| ### Protected constructors |
|---|
| `https://developer.android.com/reference/androidx/car/app/Screen#Screen(androidx.car.app.CarContext)(@https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/car/app/CarContext carContext)` |

| ### Public methods |
|---|---|
| `final void` | `https://developer.android.com/reference/androidx/car/app/Screen#finish()()` Removes this screen from the stack, which will move its lifecycle state down to `https://developer.android.com/reference/androidx/lifecycle/Lifecycle.State#DESTROYED`. |
| `final @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/car/app/CarContext` | `https://developer.android.com/reference/androidx/car/app/Screen#getCarContext()()` Returns the `https://developer.android.com/reference/androidx/car/app/CarContext` of the `https://developer.android.com/reference/androidx/car/app/CarAppService`. |
| `final @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/lifecycle/Lifecycle` | `https://developer.android.com/reference/androidx/car/app/Screen#getLifecycle()()` Returns this screen's lifecycle. |
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/Nullable.html https://developer.android.com/reference/java/lang/String.html` | `https://developer.android.com/reference/androidx/car/app/Screen#getMarker()()` Retrieves the `marker` that has been set for this screen, or `null` if one has not been set. |
| `final @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/car/app/ScreenManager` | `https://developer.android.com/reference/androidx/car/app/Screen#getScreenManager()()` Returns the `https://developer.android.com/reference/androidx/car/app/ScreenManager` to use for pushing/removing screens. |
| `final void` | `https://developer.android.com/reference/androidx/car/app/Screen#invalidate()()` Requests the current template to be invalidated, which eventually triggers a call to `https://developer.android.com/reference/androidx/car/app/Screen#onGetTemplate()` to get the new template to display. |
| `abstract @https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html https://developer.android.com/reference/androidx/car/app/model/Template` | `https://developer.android.com/reference/androidx/car/app/Screen#onGetTemplate()()` Returns the `https://developer.android.com/reference/androidx/car/app/model/Template` to present in the car screen. |
| `void` | `https://developer.android.com/reference/androidx/car/app/Screen#setMarker(java.lang.String)(@https://jspecify.dev/docs/api/org/jspecify/annotations/Nullable.html https://developer.android.com/reference/java/lang/String.html marker)` Updates the marker for this screen. |
| `void` | `https://developer.android.com/reference/androidx/car/app/Screen#setResult(java.lang.Object)(@https://jspecify.dev/docs/api/org/jspecify/annotations/Nullable.html https://developer.android.com/reference/java/lang/Object.html result)` Sets the `result` that will be sent to the `https://developer.android.com/reference/androidx/car/app/OnScreenResultListener` that was given when pushing this screen onto the stack using `https://developer.android.com/reference/androidx/car/app/ScreenManager#pushForResult(androidx.car.app.Screen,androidx.car.app.OnScreenResultListener)`. |

## Protected constructors

### Screen

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/car-app#1.0.0)

```
protected Screen(@NonNull CarContext carContext)
```

## Public methods

### finish

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/car-app#1.0.0)

```
public final void finish()
```

Removes this screen from the stack, which will move its lifecycle state down to `https://developer.android.com/reference/androidx/lifecycle/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

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/car-app#1.0.0)

```
public final @NonNull CarContext getCarContext()
```

Returns the `https://developer.android.com/reference/androidx/car/app/CarContext` of the `https://developer.android.com/reference/androidx/car/app/CarAppService`.

### getLifecycle

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/car-app#1.0.0)

```
public final @NonNull Lifecycle getLifecycle()
```

Returns this screen's lifecycle.

Here are some ways you can use a Screen's `https://developer.android.com/reference/androidx/lifecycle/Lifecycle`:

- Observe its `https://developer.android.com/reference/androidx/lifecycle/Lifecycle` by calling `https://developer.android.com/reference/androidx/lifecycle/Lifecycle#addObserver(androidx.lifecycle.LifecycleObserver)`. You can use the `https://developer.android.com/reference/androidx/lifecycle/LifecycleObserver` to take specific actions whenever the screen receives different `https://developer.android.com/reference/androidx/lifecycle/Lifecycle.Event`s.
- Use this Screen to observe `https://developer.android.com/reference/androidx/lifecycle/LiveData`s that may drive the backing data for your templates.

What each `https://developer.android.com/reference/androidx/lifecycle/Lifecycle.Event` means for a screen:

`https://developer.android.com/reference/androidx/lifecycle/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 `https://developer.android.com/reference/androidx/car/app/Screen#onGetTemplate()` at a point after this call. This is where you can make decision on whether this `https://developer.android.com/reference/androidx/car/app/Screen` is still relevant, and if you choose to not return a `https://developer.android.com/reference/androidx/car/app/model/Template` from this `https://developer.android.com/reference/androidx/car/app/Screen` call `https://developer.android.com/reference/androidx/car/app/Screen#finish()`.

`https://developer.android.com/reference/androidx/lifecycle/Lifecycle.Event#ON_START`

:   The template returned from this screen is visible in the car screen.

`https://developer.android.com/reference/androidx/lifecycle/Lifecycle.Event#ON_RESUME`

:   The user can now interact with the template returned from this screen.

`https://developer.android.com/reference/androidx/lifecycle/Lifecycle.Event#ON_PAUSE`

:   The user can no longer interact with this screen's template.

`https://developer.android.com/reference/androidx/lifecycle/Lifecycle.Event#ON_STOP`

:   The template returned from this screen is no longer visible.

`https://developer.android.com/reference/androidx/lifecycle/Lifecycle.Event#ON_DESTROY`

:   This screen is no longer valid and is removed from the screen stack.

Listeners that are added in `https://developer.android.com/reference/androidx/lifecycle/Lifecycle.Event#ON_START`, should be removed in `https://developer.android.com/reference/androidx/lifecycle/Lifecycle.Event#ON_STOP`.

Similarly, listeners that are added in `https://developer.android.com/reference/androidx/lifecycle/Lifecycle.Event#ON_CREATE` should be removed in `https://developer.android.com/reference/androidx/lifecycle/Lifecycle.Event#ON_DESTROY`.

| See also |
|---|---|
| `https://developer.android.com/reference/androidx/lifecycle/LifecycleObserver` |   |

### getMarker

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/car-app#1.0.0)

```
public @Nullable String getMarker()
```

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

| See also |
|---|---|
| `https://developer.android.com/reference/androidx/car/app/Screen#setMarker(java.lang.String)` |   |

### getScreenManager

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/car-app#1.0.0)

```
public final @NonNull ScreenManager getScreenManager()
```

Returns the `https://developer.android.com/reference/androidx/car/app/ScreenManager` to use for pushing/removing screens.

### invalidate

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/car-app#1.0.0)

```
public final void invalidate()
```

Requests the current template to be invalidated, which eventually triggers a call to `https://developer.android.com/reference/androidx/car/app/Screen#onGetTemplate()` to get the new template to display.

If the current `https://developer.android.com/reference/androidx/lifecycle/Lifecycle.State` of this screen is not at least `https://developer.android.com/reference/androidx/lifecycle/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 `https://developer.android.com/reference/androidx/car/app/Screen#onGetTemplate()`.

To avoid race conditions with calls to `https://developer.android.com/reference/androidx/car/app/Screen#onGetTemplate()` you should call this method with the main thread.

| Throws |
|---|---|
| `https://developer.android.com/reference/androidx/car/app/HostException` | if the remote call fails |

### onGetTemplate

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/car-app#1.0.0)

```
public abstract @NonNull Template onGetTemplate()
```

Returns the `https://developer.android.com/reference/androidx/car/app/model/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 `https://developer.android.com/reference/androidx/car/app/Screen#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:

- `https://developer.android.com/reference/androidx/car/app/navigation/model/NavigationTemplate`
- `https://developer.android.com/reference/androidx/car/app/model/PaneTemplate`
- `https://developer.android.com/reference/androidx/car/app/model/MessageTemplate`

**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 before closing the app.** 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 `https://developer.android.com/reference/androidx/car/app/Screen` instances onto the `https://developer.android.com/reference/androidx/car/app/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 `https://developer.android.com/reference/androidx/car/app/model/ListTemplate` does not count against the quota. See the documentation of individual `https://developer.android.com/reference/androidx/car/app/model/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 `https://developer.android.com/reference/androidx/car/app/Screen` from the `https://developer.android.com/reference/androidx/car/app/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 `https://developer.android.com/reference/androidx/car/app/Screen`, an app must send a `https://developer.android.com/reference/androidx/car/app/model/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 `https://developer.android.com/reference/androidx/car/app/model/Template` classes have special semantics that signify the end of a task. For example, the `https://developer.android.com/reference/androidx/car/app/navigation/model/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 `https://developer.android.com/reference/androidx/car/app/model/Template` classes to see which ones trigger a reset on the host.

If the host receives an `https://developer.android.com/reference/android/content/Intent.html` 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 `https://developer.android.com/reference/androidx/car/app/notification/CarAppExtender` for details on notifications.

### setMarker

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/car-app#1.0.0)

```
public void setMarker(@Nullable 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 `https://developer.android.com/reference/androidx/car/app/ScreenManager#popTo(java.lang.String)`.

### setResult

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/car-app#1.0.0)

```
public void setResult(@Nullable Object result)
```

Sets the `result` that will be sent to the `https://developer.android.com/reference/androidx/car/app/OnScreenResultListener` that was given when pushing this screen onto the stack using `https://developer.android.com/reference/androidx/car/app/ScreenManager#pushForResult(androidx.car.app.Screen,androidx.car.app.OnScreenResultListener)`.

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 `https://developer.android.com/reference/androidx/car/app/Screen#finish()`.

| Parameters |
|---|---|
| `@https://jspecify.dev/docs/api/org/jspecify/annotations/Nullable.html https://developer.android.com/reference/java/lang/Object.html result` | the value to send to the `https://developer.android.com/reference/androidx/car/app/OnScreenResultListener` that was given when pushing this screen onto the stack using `https://developer.android.com/reference/androidx/car/app/ScreenManager#pushForResult(androidx.car.app.Screen,androidx.car.app.OnScreenResultListener)` |