Android Development Standards
These standards apply to all Android application code unless a specific project document explicitly says otherwise. When in doubt, follow these conventions.
1. Technology and language
- Prefer Kotlin for all new Android code.
- Use Jetpack Compose for UI in new features. Use XML layouts only when:
- Modifying existing XML based screens.
- Integrating legacy components that are not Compose ready.
- Use Android Jetpack libraries where appropriate:
ViewModel,LiveDataorStateFlow,Navigation,Room,DataStore,WorkManager.
When a module is already heavily based on Java or XML, follow the existing style in that module and avoid mixing paradigms without a clear and incremental migration plan.
2. Architecture
Follow clean architecture with clear separation of concerns.
- Use MVVM as the default presentation pattern.
- Structure code into layers:
presentationfor UI and ViewModels.domainfor use cases and business logic.datafor repositories and data sources.
- ViewModels:
- Expose UI state via
StateFlow,SharedFloworMutableStatefor Compose. - Keep Android framework types out of the domain layer.
- Expose UI state via
- Repositories:
- Hide data source and caching details from the rest of the app.
- Expose suspend functions or reactive streams for consumption.
3. Project structure
Prefer a modular structure in larger apps.
- Split into modules such as:
corefor shared utilities, design system, common models.feature-*modules per screen or feature.data-*modules per data source when complex enough.
- Avoid creating new modules for trivial features. Default to placing code in existing relevant modules.
Use consistent and meaningful package names:
com.company.app.feature.namecom.company.app.core.uicom.company.app.data.api
4. UI and Compose standards
- Maintain a single source of truth for UI state per screen.
- Write composable functions that:
- Are small, focused and composable.
- Receive all dynamic data and callbacks via parameters.
- Do not access repositories, data sources or navigation directly.
- Use a central design system:
- Centralise colours, typography, shapes and spacing in a
designsystemorcore/uimodule. - Avoid hard coded values in composables. Use theme tokens instead.
- Centralise colours, typography, shapes and spacing in a
- Model screen states explicitly, for example:
- Loading
- Content
- Empty
- Error
- Accessibility:
- Provide
contentDescriptionfor important images and icons. - Ensure tap targets are large enough and layouts support dynamic font sizes.
- Provide
5. Navigation
- Use the Navigation Component or Compose Navigation for in app navigation.
- Define routes or destinations in a single place per feature.
- Pass only minimal arguments between screens. Prefer IDs over full objects.
- Do not store
NavControllerin ViewModels. Pass it from composables or use navigation events from ViewModels that are handled in the UI layer.
6. Data, networking and persistence
- Use a dedicated networking layer:
- Prefer Retrofit with OkHttp for HTTP APIs when suitable.
- Model responses with data classes and map them into domain models.
- Error handling:
- Wrap remote calls in a result type, such as
Result<T>or a sealed class. - Distinguish clearly between:
- Network errors.
- Server errors.
- Business rule or validation errors.
- Wrap remote calls in a result type, such as
- Persistence:
- Use Room for structured data and DataStore for key value preferences.
- Keep database entities separate from domain models. Map explicitly between layers.
- Do not block the main thread:
- Use coroutines with
Dispatchers.IOfor IO and heavy work. - Ensure any expensive computation runs off the UI thread.
- Use coroutines with
7. Dependency injection
- Use Hilt as the default dependency injection framework in new projects.
- Provide Hilt modules for:
- Network clients.
- Repositories.
- Use cases and other core services.
- Do not manually construct dependencies inside ViewModels or composables.
8. Coroutines and concurrency
- Use structured concurrency:
- Launch coroutines in appropriate scopes such as
viewModelScopeorlifecycleScope. - Ensure work is cancelled when the owning scope is cancelled.
- Launch coroutines in appropriate scopes such as
- Use
suspendfunctions for long running or IO operations. - Avoid
GlobalScopeexcept for initialisation that must live for the entire process lifetime and is explicitly safe.
9. Testing
- Types of tests:
- Unit tests for ViewModels, use cases and pure logic.
- Instrumentation tests for persistence and integration with Android components.
- UI tests using Compose testing APIs, or Espresso for legacy views.
- Testing rules:
- Cover new ViewModel and use case logic with tests.
- Mock external dependencies instead of calling real services.
- Keep tests deterministic, isolated and fast.
10. Performance and reliability
- Avoid unnecessary recompositions in Compose:
- Hoist state where possible and use stable data structures.
- Use
rememberonly where it avoids work and does not hide state.
- Use pagination for lists that can grow large.
- Use
WorkManagerfor background work that must be guaranteed or persisted. - Monitor startup time and memory usage. When optimisation is needed, measure first, then change code based on data.
11. Security and privacy
- Do not store secrets in source code or in the app binary.
- Use secure storage for sensitive user data according to platform guidance.
- Follow platform recommendations for permissions:
- Request permissions as late as possible, near the feature that needs them.
- Provide rationale dialogs when appropriate.
- When handling personal data, adhere to project specific privacy, compliance and regulatory requirements.
12. AI coding agent guidance
When acting as an AI coding agent on Android tasks:
- Respect existing project patterns and constraints before introducing new libraries or frameworks.
- When adding dependencies:
- Justify why they are needed.
- Update relevant Gradle files consistently, including version catalogues if present.
- Prefer small, incremental changes over large refactors. Preserve behaviour unless a change is explicitly requested.
- Clearly explain:
- Breaking changes.
- Migration steps.
- Any required manual changes or configuration updates for the team.
微信扫一扫