| title | sidebar_label |
|---|---|
Android architecture |
Architecture |
The Android project for Home Assistant started in 2019. Since then, the Android ecosystem has evolved significantly, and many contributors have shaped the project. As a result, you may encounter legacy code that does not adhere to current best practices. This documentation serves as the source of truth for the app's architecture and development practices.
Home Assistant has been a frontrunner in PWA development, and this philosophy is reflected in the native application. The app's centerpiece is a WebView, which integrates with Home Assistant's frontend. Over time, native capabilities have been added, such as background sensor data collection.
The entire codebase is written in Kotlin, ensuring modern, concise, and type-safe development.
- Target SDK: We aim to keep up with the latest Android SDK releases and test new versions as they are released.
- Min SDK: To ensure broad compatibility, the app supports Android Lollipop (API 21).
We follow Google's recommended Android architecture and draw inspiration from the NowInAndroid repository.
The project uses multiple Gradle modules. Shared logic is centralized in a separate Gradle project named build-logic, included in the main project via includeBuild.
To share code across different applications, we use a common Gradle module named :common.
All new UI components are built using Jetpack Compose, ensuring a modern and declarative approach to UI development.
Some legacy XML layouts, databinding, and viewbinding still exist in the app. These should be replaced with Compose as part of ongoing modernization efforts.
The app uses multiple themes to support both legacy XML and Compose-based UI. All new components should use HomeAssistantAppTheme, which is based on Material Design.
We use Hilt extensively for dependency injection, ensuring modular and testable code.
All concurrency is handled using Kotlin Coroutines, providing a structured and efficient way to manage asynchronous tasks.
We use Foreground Services for retrieving sensor values and uploading them to Home Assistant Core asynchronously.
The app maintains a direct connection to Home Assistant Core's WebSocket using OkHttp. This is essential for features like Assist and real-time discussions.
Communication with Home Assistant's REST API is handled using Retrofit, enabling seamless interaction with the backend.
- Room: User data is stored locally using Room, which provides a robust database solution.
- SharedPreferences: For app-specific settings, we use SharedPreferences with an abstraction layer named
LocalStorage.
The app supports deep linking using homeassistant:// URLs to navigate to specific parts of the app. For more details, refer to the user documentation.
The automotive application reuses the sources of the :app module, simplifying development.
The Wear OS app communicates with the mobile app to retrieve credentials for the Home Assistant server and other configurations using the Messaging API. It only works with the full flavor, as it requires Google Play Services. Once the initial setup is complete, all further communication is handled directly with Home Assistant through the WebSocket and the webhook that is created for the app.
The Android app's WebView acts as a bridge between the Home Assistant frontend and native Android capabilities. This architecture enables external authentication and external bus messaging between the frontend and native code.
flowchart TB
subgraph WebView
JS[Home Assistant Frontend JS]
end
subgraph Bridge
JsBridge[FrontendJsBridge]
end
subgraph Handler
MsgHandler[FrontendMessageHandler]
end
subgraph Repositories
ExternalBusRepo[FrontendExternalBusRepository]
SessionMgr[ServerSessionManager]
end
JS -->|"getExternalAuth()"| JsBridge
JS -->|"revokeExternalAuth()"| JsBridge
JS -->|"externalBus()"| JsBridge
JsBridge -->|"FrontendJsHandler"| MsgHandler
MsgHandler -->|"onMessageReceived()"| ExternalBusRepo
MsgHandler -->|"getExternalAuth()"| SessionMgr
MsgHandler -->|"revokeExternalAuth()"| SessionMgr
SessionMgr -->|"ExternalAuthResult"| MsgHandler
SessionMgr -->|"RevokeAuthResult"| MsgHandler
ExternalBusRepo -->|"incomingMessages()"| MsgHandler
MsgHandler -->|"send()"| ExternalBusRepo
ExternalBusRepo -->|"scriptsToEvaluate()"| JS
MsgHandler -->|"evaluateScript()"| ExternalBusRepo
- FrontendJsBridge: JavaScript interface exposed to the WebView that receives calls from the frontend
- FrontendMessageHandler: Central message handler that routes requests between the frontend and native components
- FrontendExternalBusRepository: Manages bidirectional message passing for the external bus protocol, parsing JSON messages into strongly-typed data structures
- ServerSessionManager: Handles authentication token management for external authentication