A resettable Android practice project built around a realistic 90-minute coding task. It uses Jetpack Compose, ViewModel, StateFlow, coroutines, Retrofit, Hilt, nullable API DTOs, unit tests, and Compose UI tests.
The app searches GitHub repositories. The UI is already implemented; the core data and reactive
state behavior are intentionally missing in the starter flavor.
- Open this folder in Android Studio.
- Wait for Gradle sync to finish and select JDK 21 if Android Studio asks.
- Select the
starterDebugbuild variant. - Run the app on an emulator or device.
Command-line equivalents:
./gradlew :app:assembleStarterDebug
./gradlew :app:installStarterDebugThe starter app compiles but intentionally does not load results. That is the exercise, not a setup failure.
Do not open app/src/solution yet.
- Set a 90-minute timer.
- Read the interview brief twice.
- Work only in these starter files, in order:
app/src/starter/java/com/jiahaoliuliu/androidgeneralexercise/data/RepositoryMapper.ktapp/src/starter/java/com/jiahaoliuliu/androidgeneralexercise/data/DefaultRepositorySearchRepository.ktapp/src/starter/java/com/jiahaoliuliu/androidgeneralexercise/presentation/RepositorySearchViewModel.kt
- Run one focused test after each step.
- Use the app and explain every state transition aloud.
- Spend the final ten minutes on tests, naming, cleanup, and trade-offs.
The starter unit suite should fail before you implement the TODOs:
./gradlew :app:testStarterDebugUnitTestFocused feedback:
./gradlew :app:testStarterDebugUnitTest --tests '*RepositoryMapperTest'
./gradlew :app:testStarterDebugUnitTest --tests '*DefaultRepositorySearchRepositoryTest'
./gradlew :app:testStarterDebugUnitTest --tests '*RepositorySearchViewModelTest'When you finish, compare against the reference flavor:
./gradlew :app:testSolutionDebugUnitTest
diff -ru app/src/starter/java app/src/solution/javaRead graded hints only when stuck. Read the solution walkthrough only after your attempt.
View (Compose + lifecycle-aware collection)
↓ UI events / StateFlow
ViewModel (debounce + latest-request cancellation + retry)
↓ suspend repository contract
Repository (failure translation + DTO mapping)
↓ Retrofit suspend API
GitHub Search API
app/src/main: UI, contracts, DTOs, Retrofit/Hilt setup shared by both flavors.app/src/starter: compiling TODO implementation used for practice.app/src/solution: complete reference implementation.app/src/test: mapper, repository, Flow, cancellation, retry, and error unit tests.app/src/androidTest: state-driven Compose behavior tests.docs: interview brief, hints, discussion prompts, testing, and extension drills.