Skip to content

UI Lifecycle

Overview

The lifecycle of M2Screen and M2Drawable changes according to the state of the glasses connection and the screen stack.

In Maverick AI, the glasses maintain an on-device drawing list. The SDK sends draw commands once when objects are created, then only transmits incremental deltas when properties change. The glasses render the scene continuously on their embedded OS. Animators and LOS updates are processed entirely on-device, so the phone only needs to send lightweight control commands.

Screen Stack

M2ScreenService manages screens as a stack. Only the topmost screen is active and rendered on the glasses.

  • addScreen(screen) - pushes a screen onto the stack. If it becomes topmost and the glasses are ready, onCreate() is called. If a previous screen was topmost, it receives onRelease().
  • removeScreen(screen) - removes a screen from the stack. If it was the topmost screen, onRelease() is called. The next screen in the stack becomes topmost and its onCreate() fires.
sequenceDiagram
    participant App
    participant Service as M2ScreenService
    participant A as ScreenA
    participant B as ScreenB
    App->>Service: addScreen(ScreenA)
    Service->>A: onCreate()
    Note over Service: Stack: [ScreenA]
    App->>Service: addScreen(ScreenB)
    Service->>A: onRelease()
    Service->>B: onCreate()
    Note over Service: Stack: [ScreenA, ScreenB]
    App->>Service: removeScreen(ScreenB)
    Service->>B: onRelease()
    Service->>A: onCreate()
    Note over Service: Stack: [ScreenA]

This enables patterns like overlaying a temporary screen (settings, alerts) on top of a main screen, then returning to it by removing the overlay.

Screen Lifecycle

M2ScreenService manages a stack of screens and renders the topmost screen. When a screen becomes topmost and the glasses are ready, onCreate() is called. The draw loop then repeatedly calls onBeforeDraw() before each frame. When the screen is removed or the glasses disconnect, onRelease() is called.

stateDiagram-v2
    direction TB
    [*] --> Added: addScreen()
    Added --> Created: glasses ready and screen is topmost
    Created --> DrawLoop: onCreate()
    state "Draw loop" as DrawLoop {
        direction LR
        [*] --> BeforeDraw
        BeforeDraw: onBeforeDraw(timestamp)
        Send: SDK sends command deltas
        Wait: wait for next tick
        BeforeDraw --> Send
        Send --> Wait
        Wait --> BeforeDraw
    }
    DrawLoop --> Released: removeScreen() / disconnect / no longer topmost
    Released: onRelease()
    Released --> [*]

Tick rate is configured per screen via M2Screen.setRenderingRate() using the M2RenderingRate enum - preset values are Normal (45 ms, the default), Fast (30 ms), Video (60 ms), and PowerSaving (480 ms).

Screen lifecycle callbacks:

Method Description
onCreate() Called when the screen is the topmost screen and the glasses are ready. Use to create UI elements and add them to the screen.
onBeforeDraw(timestamp) Called before each draw cycle. Use to update your screen's UI elements to their latest state.
onRelease() Called when the screen is released: removed from stack, glasses disconnect, or no longer topmost. Use to clean up resources.
onTouch(touch) Called when a touch event is received from the glasses. Override to handle touch interactions.

M2Drawable Lifecycle

M2Drawable is the base class for all visual elements drawn on the glasses. When a drawable's owning screen is created, the drawable's onCreate() is called. During the draw loop, onBeforeDraw() is called before each frame to let you update properties. When the screen is released, onBeforeRelease() is called.

stateDiagram-v2
    direction TB
    [*] --> AddedToTree: add to M2Screen tree
    state "Added to tree" as AddedToTree
    AddedToTree --> Created: screen.onCreate() runs
    Created: onCreate()
    Created --> DrawLoop
    state "Draw loop" as DrawLoop {
        direction LR
        [*] --> BeforeDraw
        BeforeDraw: onBeforeDraw(timestamp, tick)
        Serialize: serialize changed properties
        Sync: sync to glasses
        Wait: wait for next tick
        BeforeDraw --> Serialize
        Serialize --> Sync
        Sync --> Wait
        Wait --> BeforeDraw
    }
    DrawLoop --> Releasing: screen released
    Releasing: onBeforeRelease()
    Releasing --> [*]

The tick rate that drives this loop is the same M2RenderingRate configured on the parent screen - see M2Screen.setRenderingRate().

M2Drawable lifecycle callbacks:

Method Description
onCreate() Called when the drawable is created along with its screen. Use to initialize content and default properties.
onBeforeDraw(timestamp, tick) Called before each draw cycle. Use to update the element to its most current state.
onBeforeRelease() Called just before the drawable is released. Use to clean up resources.
onTopmostChanged(isTopmost) Called when the owning screen's topmost status changes.

On-Device Rendering Model

Unlike Maverick 1 where every frame was composed on the phone and streamed to the glasses, Maverick AI offloads rendering entirely to the glasses:

Aspect Maverick 1 Maverick AI
Frame rendering Phone composes each frame Glasses render on-device at ~67 Hz
Data sent per frame Full frame bitmap Only property deltas
Animations Phone computes each frame Glasses run animators on-device
LOS updates Phone re-renders for each update Glasses reposition objects on-device
Bandwidth High (continuous stream) Low (sparse commands)

Screen Events

In addition to overriding lifecycle methods, you can register listeners on M2ScreenService:

IM2ScreenEvents - screen stack changes:

Callback Description
onTopmostScreenChanged(prev, current) The visible screen changed.
onPreviewEnableChanged(enabled) Phone preview mode toggled.
onRenderingCenterChanged(x, y) Display rendering offset adjusted.

IM2ScreenDrawEvents - draw timing:

Callback Description
onBeforeDraw(timestamp) Called immediately before the frame draw begins.

Preview Mode

Phone preview can be toggled with:

Evs.screenService.enablePreview(true)
Evs.shared.screenService.enablePreview(enable: true)

This renders the glasses display on the phone screen, useful during development and debug sessions.

Phone preview rendering may differ slightly from the actual glasses display, particularly for LOS AR content. Always validate on real hardware before publishing.


See Also