Code Quality & Lint
Architecture and modularization organize where code lives. This lesson covers tools that catch problems inside the code itself — bugs, wasted resources, and inconsistent style — before they reach a user's device, using RecipeBox as the project being checked.
Android Lint
Android Lint ships built into the Android Gradle plugin — no extra dependency needed. It's a static analysis tool that scans a project's source without running it, looking for correctness bugs, performance issues, accessibility gaps, and unused resources.
Run from Gradle: the lint task analyzes the whole module.
./gradlew lint
Run from Android Studio: Analyze → Inspect Code… (or Analyze → Run Inspection by Name) runs the same checks with a UI for browsing results.
Reading a Lint Report
The Gradle lint task writes an HTML report (and an XML one) under each module's build/reports/ folder, grouped by severity and issue type.
app/build/reports/lint-results-debug.html
A Real Lint Warning
A common one in a RecipeBox-style app: calling a location or camera API without first checking that the runtime permission was actually granted.
// Lint warning: MissingPermission
public void attachPhotoFromCamera() {
cameraManager.openCamera(cameraId, stateCallback, null); // flagged: permission not verified here
}
Suppressing a False Positive
Occasionally Lint flags something that's genuinely fine for a specific, understood reason. @SuppressLint silences a specific check on a specific method or class — it should never be reached for reflexively.
@SuppressLint("MissingPermission")
public void attachPhotoFromCamera() {
// Permission is already verified one call up, in onRequestPermissionsResult()
cameraManager.openCamera(cameraId, stateCallback, null);
}
Beyond Built-In Lint
A few optional tools are commonly added on top of Lint for teams that want more:
| Tool | Focus |
|---|---|
| Checkstyle | Enforces a consistent code style (naming, formatting, import order) |
| PMD | Flags suspicious patterns — unused variables, overly complex methods |
| SpotBugs | Analyzes compiled bytecode for likely bugs (null dereferences, resource leaks) |
Code Review Habits
Tools catch what they're programmed to catch; a human reviewer catches everything else. A few habits that keep RecipeBox's codebase healthy as more people (or more time) touch it:
- Consistent naming: RecipeRepository, not a mix of RecipeRepo, RecipesDataSource, and RecipeManager for the same concept.
- Small, focused pull requests: a change that adds recipe search shouldn't also silently reformat unrelated files.
- Read the diff as a reviewer would: does this method still do one thing? Does the name still describe what it does?
- Treat a Lint warning in a diff as a discussion point, not something to auto-suppress to unblock a merge.
Hands-On Practice
- Run ./gradlew lint on a real project and open the generated HTML report.
- Fix one genuine warning it finds (not a suppression) — commonly an unused resource or a hardcoded string.
- Find one place where @SuppressLint might be legitimately needed, and write the comment explaining why.