A home screen widget doesn't run in your process. The launcher draws it from RemoteViews, a serialized description of a view tree built from a small set of allowed layouts and widgets. Jetpack Glance 234 (androidx.glance:glance-appwidget and glance-material3, 1.2.0, 26 August 2026) lets you write that tree with composable functions and translates the result into RemoteViews. The functions look like Compose 234 but are Glance's own (androidx.glance.text.Text, Column, GlanceModifier). A Hilt entry point gives the widget the app's Room 234 DAO and sync store:
@EntryPoint
@InstallIn(SingletonComponent::class)
interface WidgetEntryPoint {
fun bookDao(): BookDao
fun syncStore(): DataStore<SyncState>
}
class BookNestWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {
val deps = EntryPointAccessors.fromApplication(context, WidgetEntryPoint::class.java)
provideContent { // Glance composables, not Compose UI
// 5.30.5 collect inside the composition, so every change in Room redraws the widget
val books by deps.bookDao().observeAll().collectAsState(initial = emptyList())
val sync by deps.syncStore().data.collectAsState(initial = SyncState())
val at = if (sync.at == 0L) "not yet" else clock.format(Instant.ofEpochMilli(sync.at))
...
GlanceTheme { WidgetContent(books.sortedBy { it.price }.take(3), books.size, at) }
}
}
}
...
class BookNestWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = BookNestWidget()
}WidgetContent is a Column of Rows using GlanceTheme.colors (wallpaper-based on Android 12+) and a clickable(actionStartActivity<MainActivity>()). The manifest declares the receiver with an appwidget-provider XML file (3 by 2 cells, resizable, a picker description). Since Android 8 the app can also offer the widget itself:
val shown = GlanceAppWidgetManager(context)
.requestPinGlanceAppWidget(BookNestWidgetReceiver::class.java)The launcher answers with its own sheet (right of the figure in Notification Channels); after "Add to home screen" the log showed the request and the system binding the new widget to BookNest's receiver:
I/BookNestWidget( 8183): pin request shown=true
I/AppWidgetServiceImpl( 681): Bound widget 2 to provider ProviderId{user:0, app:10216, cmp:...