Android Architecture Starter Templates (beta) Example.
Features: Reactive MVVM arch with Kotlin Flows RoomDB Hilt Declarative with ComposeUI Bill of Materials (BoM) All Composable(s) have a preview.
We use Accompanist as it is maintained by the Google Android Compose Team. Accompanist is a group of libraries that aim to supplement Jetpack Compose with features that are commonly required by developers but not yet available.
================== Android GraphQL Tutorial Android GraphQL Example
Yelp Docs Yelp GraphQL Test Yelp GraphQL
Apollo GraphQL tutorial Apollo Compose Code Download Schema
Architecture Learning Journey Modularization Learning Journey
Thoughts: Now in Android img app free one
Google Arch Guidelines:
- Data Layer
- UI Layer
- Domain Layer
The Data Layer: Data with business logic made of
Repositories -connect to -> Data Sources (Remote or local) only one source of data
Repositories: 1. Expose data, 2. Centralize changes, 3. Resolve conflicts, 4 Contain business logic (domain layer) Each to only one data source. (ie. data vs payments)
Single source of truth. The repository should update/resolve local cache when connecting to the API
Data Immutability is done with Kotlin data class. Use different data classes for various layers.
Errors: use Kotlin Flow catch operator. Testing: Use Room in memory database for local data testing. Use fake data with DI. WireMock for network test.
The UI Layer: UI Elements / State Holders - App State -
- App data -> UI data
- UI data -> UI elements
- User events -> UI changes
UiState: use Kotlin data class ViewModel is a state holder (Unidirectional data flow)
- ViewModel exposes UI state
- UI notifies ViewModel of events
- ViewModel updates state and is consumed by the UI
UI is updated by state exposure using Kotlin Flows / Channels (StateFlow) Compose: Use mutableStateOf
UI state consumption is done by the terminal operator ".collect" Need to track the lifecycle. ViewModels last longer then then UI. Only collect when the UI is active.
UI Events.
- User Events - Actions - onClick function ()->Unit
- ViewModel Events - Exposes all the business logic need by the UI - State Update. Use uiState: StateFlow = ... errorMessages: List - using scaffoldState.snackbarhostState.showSnackbar
- refresh --
- Use LaunchedEffect - Start a coroutine from a Composable.
MainUIRoute - has all the ViewModels.
Domain Layer: only holds business logic. Has the UseCases- Naming is {verb in present tense explainig what you are doing} {noun/what} {the world UseCase} example: getLatestGymLocationUseCase
- Simple
- Lightweight
- Immutable Use Suspend functions, Flows and Callbacks to message the UI Layer. Usecase use other Usecases. Lifecycle - scoped to caller / create a new instance when passing as a dependency Threading - Must be main-safe / Move job to data layer if result can be cached.
Common Tasks:
- Encapsulate reusable business logic.
- Combine data from multiple repositories
Use a usecase to combine data that is needed by the ViewModel. Use the kotlin invoke function to make it callable: suspend operator fun invoke(): List
Usecases should be thread safe as they can be called noumerous times. Everything must go though Domain Layer.
- Reduce complexity of UI layer
- Avoid duplication
- Improve testability
Modularization Divide your project into:
- Feature modules
- Library modules
- App modules
Layers: App -only-> Feature -only-> Library
Enities - Remote Entities - JSon Response - data class RemoteUser(val userid :String, val token:String) / RemoteInventory Database Entities - @Entity using Room Domain Entities - business models - data call Inventory() - UiState - UI State - @Parcelize data class Inventory():Parcelable with mapper classes - Remote and Database = DataLayer UiState or Domain = UI Layer
data class RemoteInventory
Nice Alternative platform