A modern Android weather application built with Jetpack Compose that provides current weather information based on the user's location.
├── app/ # Main application module
│ ├── src/
│ │ ├── main/ # Main source code
│ │ │ ├── java/com/moodi/someapp/
│ │ │ │ ├── location/ # Location handling components
│ │ │ │ ├── remote/ # API and remote data components
│ │ │ │ ├── repository/ # Repository layer
│ │ │ │ ├── ui/ # UI components and theme
│ │ │ │ ├── viewmodel/ # ViewModels
│ │ │ │ ├── MainActivity.kt # Main UI entry point
│ │ │ │ └── Result.kt # Result wrapper class
│ │ │ └── res/ # Android resources
│ │ ├── test/ # Unit tests
│ │ │ └── java/com/moodi/someapp/
│ │ │ ├── location/ # Location tests
│ │ │ ├── remote/ # API tests
│ │ │ ├── repository/ # Repository tests
│ │ │ ├── ui/ # UI tests with Paparazzi
│ │ │ ├── viewmodel/ # ViewModel tests
│ │ │ └── rule/ # Test rules and utilities
│ │ └── androidTest/ # Instrumented tests
│ └── build.gradle.kts # App level build config
├── gradle/ # Gradle configuration
│ └── libs.versions.toml # Version catalog for dependencies
├── .github/ # GitHub workflows
│ └── workflows/ # CI/CD configurations
└── build.gradle.kts # Project level build config
This application follows the MVVM (Model-View-ViewModel) architecture pattern:
- Model: Repository and data classes in the
repositorypackage - View: Compose UI components in
MainActivity.ktand other Compose files - ViewModel:
WeatherViewModel.ktthat handles the UI state and business logic
The app uses a clean separation of concerns with:
- Repository pattern for data access
- Use case pattern for business logic
- Dependency injection via constructor injection
- Unidirectional data flow
- Jetpack Compose: Modern UI toolkit for building native Android UI
- AndroidX Core KTX: Kotlin extensions for Android core
- Lifecycle Runtime KTX: Lifecycle components with Kotlin coroutines
- Ktor Client: Kotlin multiplatform HTTP client
ktor-client-core: Core client functionalityktor-client-android: Android engine for Ktorktor-client-logging: HTTP request loggingktor-client-content-negotiation: Content negotiation supportktor-serialization-kotlinx-json: JSON serialization
- Kotlinx Serialization: Kotlin multiplatform serialization library
- Kotlin Coroutines: For asynchronous programming
kotlinx-coroutines-play-services: Coroutine integration with Google Play Services
- Google Play Services Location: For accessing device location
- JUnit4: Unit testing framework
- MockK: Mocking library for Kotlin
- Kotlin Coroutines Test: Testing utilities for coroutines
- Android Core Testing: Testing utilities for Android architecture components
- Turbine: Testing library for Flow
- Paparazzi: Screenshot testing library for Compose UI
- Espresso: UI testing framework for Android
- Compose Testing: Testing utilities for Jetpack Compose
- JaCoCo: Code coverage reporting tool
- Clone the repository
- Create a
local.propertiesfile in the project root with your OpenWeather API key:OPEN_WEATHER_API_KEY=your_api_key_here - Build the project using Android Studio or Gradle:
./gradlew build
The project includes comprehensive tests:
- Unit Tests: Run with
./gradlew test - UI Screenshot Tests: Run with
./gradlew verifyPaparazziDebug - Instrumented Tests: Run with
./gradlew connectedAndroidTest - Code Coverage Report: Run with
./gradlew jacocoTestReport
The project includes GitHub Actions workflows for:
- Running unit tests
- Generating code coverage reports
The following improvements are planned for this project:
- Implement consistent naming conventions across the codebase
- Refactor large methods into smaller, more focused functions
- Add comprehensive documentation including KDoc comments
- Apply SOLID principles more thoroughly
- Increase unit test coverage to at least 80%
- Add more integration tests for critical user flows
- Implement UI tests for all major screens
- Set up snapshot testing for UI components
- Consider migrating to a feature-based architecture
- Alternatively, implement a cleaner layer-based architecture
- Improve module organization for better separation of concerns
- Extract reusable components into separate modules