Review the lifetime of each resource
Ask who owns a stream, cursor, listener, executor and context reference, and when it is released. Prefer structured cleanup such as try-with-resources for compatible resource types.
try (InputStream input = resolver.openInputStream(uri)) {
if (input == null) {
throw new IOException("The selected content is unavailable");
}
// Stream and validate bounded content here.
}
This fragment illustrates cleanup and a missing stream; it is not a complete import pipeline.
Check Android-specific failure paths
| Area | Review question |
|---|---|
| Main thread | Does this path perform blocking I/O or expensive computation? |
| Activity/fragment lifecycle | Can a callback outlive the screen it updates? |
| Memory | Are large bitmaps, buffers or context references retained? |
| Permissions | Is access checked at the operation and failure handled? |
| Persistence | Can retries duplicate or corrupt a user action? |
| Security | Is untrusted input validated at the boundary? |
The memory guide, crash guidance and security recommendations provide platform context for these questions.
Reject silent catch-all handling
Catching Exception and continuing as though an operation succeeded can hide data loss. Handle expected failures with an explicit result, log redacted diagnostics and let programming defects remain discoverable through tests and monitoring.
Do not log tokens, full private documents or credentials just to make debugging easier.
Test state changes, not only the happy path
Rotate or recreate the screen, cancel the operation, revoke permission, remove connectivity and reopen the app after process loss. These tests reveal assumptions that ordinary unit tests may not exercise.
Use static checks as support
APKLint's code checker can point out suspicious patterns, but it cannot infer every lifecycle owner or execute the flow. A useful review comment names the failing state and expected behavior, then asks for a focused test—not merely a preferred style or design-pattern label.
Review an import as a resource and state transaction
For a Java document importer, identify who opens the input stream, who reads it and who closes it if parsing fails. The try-with-resources contract provides structured cleanup for compatible resources. It does not itself impose an input-size limit, validate the file or decide what partial output should survive a failure.
Review the read loop for bounded processing and the parser's failure contract. Avoid trusting a reported file size as the only limit when the provider can return a different stream. Keep an explicit limit appropriate to the feature and report an unsupported size without committing a partial document as a successful import.
Associate completion with the screen that requested it
Start import A, navigate away and begin import B on a new screen. If A finishes later, its callback must not replace B's state or retain the destroyed activity. Make the owner and result identity visible in the design. A callback that merely checks whether a field is non-null can still reference the wrong live screen.
Test a stream that cannot be opened, a malformed synthetic document and a read failure partway through processing. Confirm that resources close and the interface reaches an honest failure state in each case. Retain a valid second input to check that the failed attempt does not poison subsequent imports.
Review exception handling at the boundary. Convert expected input or access errors into useful results, while preserving enough redacted diagnostic information to investigate programming defects. A catch-all block that returns an empty document hides both failure and data loss from the caller.
Inspect how the final output is committed. If persistence occurs in stages, define cleanup or rollback for an interrupted write. A success callback should follow the successful commit, not merely the end of parsing.
Keep the review comment tied to the observed failing state and expected behavior. This gives a maintainer a concrete repair and test target without turning the discussion into a list of preferred patterns unrelated to the importer's actual ownership, limits and recovery needs.
Sources and further reading
- Android Developers: Security best practices
- Android Developers: Manage your app memory
- Android Developers: Diagnose and fix crashes
Reference review: 29 September 2026. Examples illustrate the workflow; check your installed versions, release artifact and account-specific Console requirements before applying them. This guide is not a claim that APKLint executed your project or verified your private account.


