A panel represents the intention of a Frontend to show a fragment. Panels are intended to be presented to the user by the system UI. The system UI decides whether, when and where the fragment is displayed.
A panel is created by a Frontend. The frontend provides context to the panel to complete the task, like the frontendContext. Depending on the purpose of the panel, a frontend also provides additional details, like which album to display, or the ability to add another panel.
When creating a panel, choosing the right panel type is very important. A panel type is a grouping of panels that can be placed in the same panel container. In other words, this is a hint to the system UI as to where to display a panel. See the system UI anatomy for an overview of the built-in panel types. You're not restricted to using the built-in panel types, custom panel types can be supported by a custom system UI.
The panel type can also affect whether and when a panel is displayed. A panel type can have properties that help the system UI to determine this, like MainProcessPanel.priority. The values of these properties can change over time. A panel is a LifecycleOwner to enable this.
When the system UI decides to present a panel, it attaches the IviFragment returned by createInitialFragment to its layout. The created fragment will internally instantiate a ViewModel (FrontendViewModel) with a reference to this panel.
The system UI may choose to show and stop showing the panel more than once. E.g., a panel may be temporarily detached from the system UI if a similar panel with higher priority is offered to the system UI. Each time, a new fragment, along with its ViewModel, is created and destroyed. As such, it's important to consider whether data should be stored in the ViewModel or in a service. Data that is used by the fragment typically belongs in the ViewModel. The ViewModel will be cleared when the panel is detached and attached again. Data that is important to survive detachment should be kept in a service instead.
Service connections for presenting data are commonly in the ViewModel rather than the panel to avoid keeping services alive for panels that are not attached. (Note that if the service requested in the ViewModel is already alive, creating another connection to it is a cheap operation.) It can however be beneficial for the panel to ask for a service connection in its constructor, allowing the service connection to be created by the Frontend and thus stay alive after the panel is destroyed. This allows panel contents to be populated immediately upon showing and is important when a service call must be performed upon the destruction of the panel or ViewModel, as those calls may fail when the service is closed as a result of the panel's or ViewModel's destruction. Similarly, if a call is needed when the panel is removed, it is not sufficient to perform it within ViewModel.onCleared because the ViewModel may never have been created during the panel's lifespan.
Once the panel is added to its frontend, the state is changed from Lifecycle.State.INITIALIZED to Lifecycle.State.CREATED. The lifecycle changes state to Lifecycle.State.STARTED when it is attached to the system UI. The panel can be detached and then attached again.
If the panel is dismissed or removed from the frontend, its lifecycle transitions to Lifecycle.State.DESTROYED after which it may not be added to a frontend again.