Preview Runner
viewcompose-preview-runner is the Android execution layer for deterministic static previews. It is
normally resolved by the Gradle plugin/worker host, not placed on an application runtime classpath.
It supports Android API 24+ inside Layoutlib, Paparazzi, or another controlled host.
/** Resolves application bytecode and exports one static preview response. */
fun renderCompiledPreviewSample(
context: Context,
request: PreviewRenderRequest,
applicationClassLoader: ClassLoader,
): PreviewRenderResponse {
return StaticPreviewWorker().render(context, request, applicationClassLoader)
}
Execution and ownership
PreviewJvmEntryPointResolver accepts one unambiguous public static JVM method with a single
UiTreeBuilder receiver/parameter and Unit return. An application theme provider is constructed
from Kotlin INSTANCE or a public no-argument constructor. StaticPreviewRenderer.mount verifies
descriptor/API identity, resolves Android configuration and theme, installs lifecycle, ViewModel,
saved-state, resource-environment, and theme owners, and lays out one native hierarchy.
Every successful StaticPreviewFrame must be closed. Closing destroys all frame-scoped owners and
providers; independent mounts do not share SDK state. A borrowed application class loader is not
installed as the thread context loader and is never closed by the runner.
The worker exports preview.png and render-tree.json with atomic replacement. The response records
entry resolution, mount/layout, image export, and snapshot export timings. Expected discovery,
theme, render, layout, capture, and export failures become structured responses; thread death and
out-of-memory errors escape so the host can retire.
Configuration, sizing, and diagnostics
PreviewAndroidContextFactory mirrors density, font scale, viewport, locale, direction, and
light/dark mode into Android resources and AndroidResourceEnvironment, with observation disabled.
An application PreviewThemeProvider is authoritative when present; otherwise the deterministic
Android theme bridge disables dynamic color. Requested API level must match the worker.
Fixed height uses the configured viewport. Auto height first lays out a real viewport and expands only root-growing scroll descendants, bounded by maximum dp height and a 16-megapixel capture budget. PNG capture is lossless. Immutable diagnostics include structure, native bounds, clipping, patches, composition and source locations without retaining runtime objects.
- Stability: Alpha tooling infrastructure; protocol compatibility belongs to Preview Core.
- Close every mounted frame, including assertion-only tests.
- Test fixed/auto height, nested scrollers, capture limits, RTL, locales, font scale, API matching,
application themes, and each failure phase with
:viewcompose-preview-runner:testDebugUnitTest.
See Preview Core, Worker Host, and the generated API reference.