DEV Community

Riazul Karim Ivan
Riazul Karim Ivan

Posted on

A Clean & Practical Code Review Checklist for Android Projects

In Android projects — especially large-scale, multi-module, production apps — having a consistent review checklist reduces technical debt and keeps standards aligned across the team.
They are about maintainability, scalability, performance, and team trust.
Here’s a practical checklist I use for Android projects.

1. Architecture & Design

Good architecture makes the project survivable after years.

✔ Architecture Consistency

  • Follows Clean Architecture / MVVM / MVI consistently
  • Uni-directional data flow maintained
  • Clear separation of UI / Domain / Data layers

✔ Business Logic Placement

  • No business logic inside Activities or Fragments (or compose)
  • ViewModels only handle UI-related logic
  • Domain logic lives inside UseCases

✔ UseCases

  • Single responsibility
  • Small and focused
  • No multi-purpose “God” use cases

✔ Dependency Injection

  • Hilt / Dagger properly configured
  • No manual dependency wiring
  • No service locators hidden inside code

✔ Design Principles

  • SOLID principles followed, along with others(DRY, KISS, GRASP, CQRS)
  • Reuse of existing utility functions where appropriate
  • No duplicated logic
  • No broken unit tests

2. Kotlin & Language Usage

Kotlin gives powerful tools. Use them wisely.

✔ Immutability First

  • Prefer val over var
  • Immutable state where possible ### ✔ Kotlin Types
  • Use data class for models
  • sealed class for state representation
  • enum when appropriate ### ✔ Null Safety
  • Avoid nullable chains like ?.?.?.
  • No use of !!
  • Handle nulls explicitly and safely ### ✔ Extension & Scope Functions
  • Extension functions improve readability (not dumping business logic)
  • Scope functions (let, apply, run, also, with) used meaningfully
  • No nested scope-function pyramids ### ✔ Data Structures
  • Correct usage of List, MutableList, Map, Set
  • Avoid unnecessary list copying
  • Efficient transformations (map, filter, associate, etc.)

3. UI Layer (Compose / XML)

UI should be predictable and state-driven.

Jetpack Compose

  • State hoisted properly
  • UI is stateless where possible
  • No side effects inside composables
  • Use LaunchedEffect, SideEffect, remember, derivedStateOf correctly
  • Awareness of recomposition behavior (use of key in list generate)
  • Avoid unnecessary recompositions

XML / View System

  • No heavy logic inside views
  • Avoid deeply nested layouts
  • ViewBinding enabled (no findViewById)
  • No memory leaks from view references

4. State & Async Handling

Async mistakes are expensive in production.

✔ Coroutines & Flow

  • Proper use of Flow, StateFlow, or LiveData
  • No GlobalScope
  • Cold vs hot stream usage is correct ### ✔ Dispatcher Usage
  • IO for network/database
  • Default for CPU work
  • Main for UI ### ✔ Cancellation
  • Jobs cancelled properly
  • ViewModelScope used correctly ### ✔ Avoid Blocking
  • No runBlocking in production
  • No Thread.sleep()
  • No heavy work on Main thread

5. Error Handling

Error handling defines production quality.

  • Errors modeled explicitly (Result, Either, sealed classes)
  • No silent catch {} blocks
  • User-friendly error states exposed to UI
  • Logs added meaningfully (no spam logging) 

6. Performance

Performance issues hide in small mistakes.

  • No heavy work on Main thread
  • Avoid unnecessary recompositions
  • Efficient list rendering (LazyColumn, DiffUtil)
  • Pagination or lazy loading where needed
  • No memory leaks (Context misuse, observers not cleared)

7. Testing

If it’s not tested, it’s fragile.

  • Unit tests for UseCases
  • Unit tests for ViewModels
  • UI logic is state-driven and testable
  • Mocks/Fakes used properly
  • Descriptive test names
  • Minimum coverage target followed (e.g., 80%)
  • Test functions are maintainable and readable

8. Code Quality & Readability

Code should read like documentation.

  • Small and focused functions
  • Meaningful naming (no data, temp, obj)
  • No commented-out dead code
  • Consistent formatting (ktlint, detekt)
  • No magic numbers — use constants

9. Security & Configuration

Small mistakes here can be costly.

  • No API keys or secrets inside source code
  • Tokens loaded from secure config
  • Proguard / R8 rules reviewed
  • Debug-only tools not leaking into release builds
  • Do not pass secret user-data every layer or keep in memory
  • Follow Security team guideline to avoid pentest defects/review comments

10. Git & PR Hygiene

Good PR hygiene reduces team friction.

  • PR is small and focused
  • Large tasks split into smaller subtasks
  • Clear description of what and why
  • Screenshots for UI changes
  • Screen recording for flow (even with mock data)
  • For defect fixes: include reproduction path and screen record
  • Linked ticket/task for feature or bug
  • No unrelated changes in the same PR

Final Thoughts

A good code review is not about nitpicking syntax.
It’s about protecting the future of the codebase.
When teams follow a structured checklist:

  • Bugs decrease
  • Performance improves
  • Onboarding becomes easier
  • Refactoring becomes safer (layer by layer)
  • Trust increases

Code quality is not accidental. It is enforced — consistently.

Top comments (0)