Zpět na domů

DreamService a Compose v Androidu 4.2+

DreamService umožňuje vytvářet UI ve spícím režimu Androidu při nabíjení. Integrace Jetpack Compose vyžaduje implementaci LifecycleOwner a SavedStateRegistryOwner. Podrobný průvodce s kódem pro middle/senior vývojáře.

Compose v DreamService: UI pro spící Android
Advertisement 728x90

DreamService v Androidu: Integrace s Jetpack Compose pro obrazovky ve spánkovém režimu

DreamService, který se objevil v Androidu 4.2, umožňuje zobrazovat vlastní UI na zařízení v režimu čekání během nabíjení. Komponenta dědí od Service a podporuje interaktivní prvky, včetně tlačítek. Pro aktivaci je vyžadováno manuální nastavení uživatelem v parametrech displeje. Toto řešení se hodí pro tvorbu dynamických obrazovek bez vlivu na hlavní lifecycle aplikace.

Deklarace servisu v AndroidManifest.xml je standardní:

<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>

Základní implementace využívá onAttachedToWindow() pro nastavení view:

Google AdInline article slot
class MyDreamService : DreamService() {

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()

        isInteractive = false
        isFullscreen = true
        setContentView(R.layout.dream_service_layout)
    }
}

Integrace Jetpack Compose do DreamService

Metoda setContentView funguje pouze s View, proto se pro Compose vytváří ComposeView. DreamService však neposkytuje ViewTreeLifecycleOwner a SavedStateRegistryOwner, což je kritické pro správnou funkci Compose.

Řešením je rozšíření DreamService s implementací 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
}

V onAttachedToWindow() synchronizujte lifecycle a registry:

Google AdInline article slot
val composeView = ComposeView(this).apply {
    setViewTreeLifecycleOwner(this@MyDreamService)
    setViewTreeSavedStateRegistryOwner(this@MyDreamService)
    setContent {
        DreamServiceTheme {
            DreamScreen(
                onOpenSettings = { 
                    openSettingsAndExitDream() 
                }
            )
        }
    }
}

setContentView(composeView)

Nezapomeňte volat metody lifecycle v callbackách DreamService (onAttachedToWindow, onDetachedFromWindow atd.) pro správnou synchronizaci stavů.

Klíčová omezení a best practices

  • Aktivace: Uživatel musí manuálně povolit Daydream v nastavení. Automatické spuštění není možné.
  • Lifecycle: Zajistěte úplnou implementaci LifecycleOwner pro Compose, jinak se UI neaktualizuje.
  • Výkon: Vyhněte se náročným animacím – zařízení je ve spánkovém režimu.
  • Interaktivita: isInteractive = true umožňuje tlačítka, ale vyžaduje opatrnost se spotřebou energie.

Seznam kroků pro nasazení:

  • Deklarujte servis v manifestu s permission BIND_DREAM_SERVICE.
  • Děděte od DreamService a přidejte SavedStateRegistryOwner.
  • Inicializujte LifecycleRegistry a SavedStateRegistryController.
  • V ComposeView nastavte owners před setContent.
  • Testujte na reálném zařízení v režimu nabíjení.

Co je důležité

  • DreamService je plnohodnotný UI-hoster mimo Activity, s podporou Compose po úpravě lifecycle.
  • Manuální aktivace v nastavení displeje je povinná.
  • Řešení problémů s ViewTreeLifecycleOwner prostřednictvím rozšíření servisu.
  • Vhodné pro obrazovky čekání: hodiny, notifikace, mini-hry.
  • Úspora energie je kritická – minimalizujte draw calls.

Tato funkce rozšiřuje možnosti Android vývoje, umožňující přizpůsobit chování zařízení v nestandardních scénářích. Pro seniorní vývojáře je užitečná v kontextu hlubokého pochopení platformních servisů a jejich integrace s moderními UI frameworky.

Google AdInline article slot

— Editorial Team

Advertisement 728x90

Číst dál