Android 中的 DreamService:为屏保屏幕集成 Jetpack Compose
DreamService 自 Android 4.2 引入,允许在设备充电闲置时显示自定义 UI。该组件继承自 Service,支持包括按钮在内的交互元素。激活需要用户在显示设置中手动配置。此解决方案适用于创建动态屏幕,且不影响主应用生命周期。
在 AndroidManifest.xml 中声明服务是标准步骤:
<service
android:name=".MyDreamService"
android:exported="true"
android:description="@string/dream_service_description"
android:icon="@drawable/dream_service_icon"
android:label="@string/dream_service_label"
android:permission="android.permission.BIND_DREAM_SERVICE">
<intent-filter>
<action android:name="android.service.dreams.DreamService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
基本实现使用 onAttachedToWindow() 来配置视图:
class MyDreamService : DreamService() {
override fun onAttachedToWindow() {
super.onAttachedToWindow()
isInteractive = false
isFullscreen = true
setContentView(R.layout.dream_service_layout)
}
}
将 Jetpack Compose 集成到 DreamService
setContentView 方法仅适用于 Views,因此需要为 Compose 创建 ComposeView。然而,DreamService 不提供 ViewTreeLifecycleOwner 和 SavedStateRegistryOwner,而这对于 Compose 正常运行至关重要。
解决方案是扩展 DreamService 以实现 SavedStateRegistryOwner:
class MyDreamService : DreamService(), SavedStateRegistryOwner {
private val lifecycleRegistry = LifecycleRegistry(this)
private val savedStateRegistryController = SavedStateRegistryController.create(this)
override val lifecycle: Lifecycle
get() = lifecycleRegistry
override val savedStateRegistry: SavedStateRegistry
get() = savedStateRegistryController.savedStateRegistry
}
在 onAttachedToWindow() 中,同步生命周期和注册表:
val composeView = ComposeView(this).apply {
setViewTreeLifecycleOwner(this@MyDreamService)
setViewTreeSavedStateRegistryOwner(this@MyDreamService)
setContent {
DreamServiceTheme {
DreamScreen(
onOpenSettings = {
openSettingsAndExitDream()
}
)
}
}
}
setContentView(composeView)
别忘了在 DreamService 回调(onAttachedToWindow、onDetachedFromWindow 等)中调用 lifecycle 方法,以确保状态正确同步。
关键限制与最佳实践
- 激活:用户必须在设置中手动启用屏保功能。无法自动启动。
- 生命周期:确保为 Compose 完整实现
LifecycleOwner,否则 UI 将不会更新。 - 性能:避免繁重的动画——设备处于休眠模式。
- 交互性:
isInteractive = true允许使用按钮,但需谨慎对待功耗。
实施步骤列表:
- 在清单中使用
BIND_DREAM_SERVICE权限声明服务。 - 继承
DreamService并添加SavedStateRegistryOwner。 - 初始化
LifecycleRegistry和SavedStateRegistryController。 - 在
ComposeView中,于setContent之前设置所有者。 - 在充电模式下于真实设备测试。
核心要点
- DreamService 是 Activity 之外的完整 UI 宿主,经过生命周期调整后支持 Compose。
- 必须在显示设置中手动激活。
- 通过扩展服务解决
ViewTreeLifecycleOwner问题。 - 适用于闲置屏幕:时钟、通知、迷你游戏。
- 省电至关重要——最小化绘制调用。
此功能扩展了 Android 开发能力,允许在非标准场景中定制设备行为。对于高级开发者而言,有助于深入理解平台服务及其与现代 UI 框架的集成。
— Editorial Team
暂无评论。