| name | Code Quality Audit |
| description | Systematic code review after feature development - structure, hygiene, separation of concerns, and performance |
Skill: Code Quality Audit
Last Verified: 2026-01-23
Applicable SDK: Android 14+ (API 34+)
Dependencies: best-practice-check, codebase-aware-implementation
Purpose
After completing a development phase, perform a comprehensive code quality audit focusing on production code (excluding test files). This skill provides a systematic approach to identify technical debt, architectural issues, and potential bugs before they become problems.
When to Use
- After completing a major feature or development milestone
- Before releasing a new version
- When preparing for code review or handoff
- When technical debt needs assessment
- Periodically (e.g., monthly) for ongoing projects
Audit Dimensions
1. File Structure & Organization (Project Structure)
Objective: Ensure logical, maintainable project organization
Check Points:
Commands to Run:
find ./app/src/main -type f \( -name "*.kt" -o -name "*.java" \) -exec head -1 {} \; -print
grep_search for class definitions and check package declarations
Review Questions:
- Does each package have a clear, single responsibility?
- Are feature modules properly isolated?
- Should any files be moved to better reflect their purpose?
- Is the resource organization intuitive?
2. Code Hygiene (Code Cleanliness)
Objective: Remove clutter and ensure code quality standards
Check Points:
Commands to Run:
grep_search for string literals in .kt files (exclude test files)
grep_search for "TODO" and "FIXME" in source files
grep_search for "//.*fun " or "//.*val " patterns
grep_search for "Log.d", "Log.v", "println" in source files
./gradlew lint
Review Questions:
- Are all string resources properly named and organized?
- Do constant names follow UPPER_SNAKE_CASE convention?
- Are dimension values semantic (e.g.,
button_height not size_48dp)?
- Is there dead code that can be removed?
3. Separation of Concerns (Architecture)
Objective: Ensure proper layering and responsibility distribution
Check Points:
Commands to Run:
view_file_outline for each Activity/Fragment and check method complexity
grep_search for "Context" in ViewModel files
Review Questions:
- Can each class be described in one sentence?
- Are responsibilities clearly separated between layers?
- Would a new developer understand the architecture from file organization?
- Are there any circular dependencies?
- Is dependency injection used consistently?
Red Flags:
- Activities/Fragments > 300 lines
- Methods > 50 lines
- Classes with > 10 dependencies
- Direct use of
Context in non-UI classes
- Database queries in ViewModels
- Network calls in UI layer
4. Performance & Memory (Critical Issues)
Objective: Identify memory leaks and performance bottlenecks
Check Points:
Memory Leaks
Performance Issues
Commands to Run:
grep_search for "companion object.*Context" or "static.*Context"
grep_search for "Handler(" in source files
grep_search for "Thread.sleep", ".get()" on futures, blocking IO
grep_search for "FileInputStream", "Cursor", "InputStream" without ".use"
view_code_item for custom Views and check onDraw methods
Review Questions:
- Are all lifecycle-aware components properly scoped?
- Are background operations using coroutines or WorkManager?
- Is image loading optimized with caching?
- Are there any potential ANR (Application Not Responding) risks?
Critical Patterns to Check:
companion object {
lateinit var context: Context
}
companion object {
lateinit var appContext: Application
}
class MyFragment : Fragment() {
override fun onViewCreated(...) {
someManager.addListener(this)
}
}
class MyFragment : Fragment() {
override fun onViewCreated(...) {
someManager.addListener(this)
}
override fun onDestroyView() {
someManager.removeListener(this)
super.onDestroyView()
}
}
override fun onDraw(canvas: Canvas) {
val paint = Paint()
canvas.drawCircle(x, y, radius, paint)
}
private val paint = Paint()
override fun onDraw(canvas: Canvas) {
canvas.drawCircle(x, y, radius, paint)
}
Execution Workflow
Step 1: Preparation
- Ensure all code is committed to version control
- Run a clean build:
./gradlew clean build
- Run lint:
./gradlew lint and review the report
- Note current project state (branch, last commit)
Step 2: Automated Checks
Run these commands and collect output:
find ./app/src/main -type f -name "*.kt" | grep -v Test
grep -r "TODO" app/src/main --include="*.kt"
grep -r "FIXME" app/src/main --include="*.kt"
grep -r "Log\.[dv]" app/src/main --include="*.kt"
grep -r "println" app/src/main --include="*.kt"
find ./app/src/main -name "*.kt" -exec wc -l {} \; | sort -rn | head -20
./gradlew lint
Step 3: Manual Review
For each dimension (1-4 above):
- Review check points systematically
- Use
view_file_outline to understand class structure
- Use
view_code_item to examine specific methods
- Use
grep_search to find patterns
- Document findings with file names and line numbers
Step 4: Generate Report
Create a markdown report with:
# Code Quality Audit Report
**Date**: [Current Date]
**Commit**: [Git commit hash]
**Auditor**: [Your name or "AI Assistant"]
## Executive Summary
[Brief overview of findings]
## 1. File Structure & Organization
### Issues Found
- [ ] **[Severity]** `path/to/File.kt` - [Description]
- **Line**: [Line number if applicable]
- **Suggestion**: [How to fix]
## 2. Code Hygiene
### Issues Found
- [ ] **[Severity]** `path/to/File.kt:123` - [Description]
- **Suggestion**: [How to fix]
## 3. Separation of Concerns
### Issues Found
- [ ] **[Severity]** `path/to/File.kt:45-67` - [Description]
- **Suggestion**: [How to fix]
## 4. Performance & Memory
### Critical Issues
- [ ] **HIGH** `path/to/File.kt:89` - [Memory leak description]
- **Risk**: [Explain the risk]
- **Fix**: [How to fix]
### Performance Issues
- [ ] **MEDIUM** `path/to/File.kt:123` - [Performance issue]
- **Impact**: [Explain impact]
- **Fix**: [How to fix]
## Recommendations
1. [Priority 1 recommendation]
2. [Priority 2 recommendation]
...
## Metrics
- Total files reviewed: X
- Issues found: Y
- Critical issues: Z
- Estimated effort: [hours/days]
Step 5: Prioritization
Categorize findings by severity:
- CRITICAL: Memory leaks, crashes, security issues
- HIGH: Performance problems, architectural violations
- MEDIUM: Code hygiene, minor refactoring
- LOW: Naming conventions, formatting
Output Format
For each issue found, provide:
- Severity: CRITICAL | HIGH | MEDIUM | LOW
- Category: Structure | Hygiene | Architecture | Performance
- File: Full path to the file
- Line(s): Specific line numbers
- Issue: Clear description of the problem
- Impact: Why this matters
- Suggestion: Concrete fix with code example if applicable
Example:
❌ **HIGH** - Performance & Memory
📁 `app/src/main/java/com/example/ui/MainActivity.kt:45-52`
🔍 **Issue**: Coroutine launched with GlobalScope instead of lifecycleScope
💥 **Impact**: Potential memory leak - coroutine continues after Activity destroyed
✅ **Fix**: Replace `GlobalScope.launch` with `lifecycleScope.launch`
// Before
GlobalScope.launch {
repository.loadData()
}
// After
lifecycleScope.launch {
repository.loadData()
}
Best Practices
- Exclude Test Files: Use grep/find patterns to exclude
*Test.kt, androidTest/, test/
- Focus on Impact: Prioritize issues that affect users or stability
- Be Specific: Always provide file paths and line numbers
- Provide Examples: Show before/after code for fixes
- Consider Context: Some patterns are acceptable in specific contexts
- Batch Similar Issues: Group similar issues together for efficiency
- Verify Suggestions: Ensure suggested fixes are compatible with project architecture
Tools Integration
Android Lint
./gradlew lint
Detekt (if configured)
./gradlew detekt
Manual Inspection Tools
view_file_outline: Get class structure overview
view_code_item: Examine specific methods
grep_search: Find patterns across codebase
find_by_name: Locate files by name/pattern
Common Anti-Patterns to Check
Android-Specific
- Context Leaks: Static references, singletons holding Activity context
- Lifecycle Violations: Operations after lifecycle destroyed
- Main Thread Blocking: Network/DB on UI thread
- Resource Leaks: Unclosed Cursors, Streams, Bitmaps
- Memory Churn: Allocations in
onDraw(), onMeasure()
General Code Quality
- God Classes: Classes > 500 lines or > 20 methods
- Long Methods: Methods > 50 lines
- Deep Nesting: > 3 levels of indentation
- Magic Numbers: Unexplained numeric literals
- Hardcoded Values: Strings, colors, dimensions in code
- Dead Code: Unused methods, classes, resources
- Inconsistent Naming: Mixed conventions in same project
Exclusions
Do NOT audit:
- Test files (
*Test.kt, androidTest/, test/)
- Generated code (
build/, .gradle/)
- Third-party libraries (
libs/)
- Gradle configuration (unless specifically requested)
- Documentation files (unless checking for outdated info)
Success Criteria
A successful audit should:
- ✅ Cover all production source files
- ✅ Identify critical issues (memory leaks, crashes)
- ✅ Provide actionable, specific suggestions
- ✅ Include file paths and line numbers
- ✅ Prioritize findings by severity
- ✅ Estimate effort required for fixes
- ✅ Be delivered in clear, structured format
Follow-Up Actions
After audit completion:
- Create GitHub issues or task tickets for each finding
- Prioritize fixes in upcoming sprints
- Address CRITICAL issues immediately
- Schedule refactoring for HIGH/MEDIUM issues
- Consider adding lint rules to prevent recurrence
- Update coding guidelines based on findings
- Schedule next audit (recommend: after each major feature)