Android/APIExample/.agent/skills/review-case/SKILL.md
Review an existing case implementation against project-specific red lines and coding standards. Use after implementing or modifying a case. Use when: reviewing a case for correctness, checking red-line compliance, verifying lifecycle and threading patterns, auditing an existing Fragment. Keywords: review, audit, check, red lines, lifecycle, threading, compliance.
npx skillsauth add agoraio/api-examples review-caseInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Run through every item below before considering a case implementation complete. Open the case's Fragment source file and verify each point against the actual code.
[ ] leaveChannel before destroy — engine.leaveChannel() is called before RtcEngine.destroy() in the teardown path (typically onDestroy()). Destroying without leaving first leaks the channel session on the server side.
[ ] handler.post for destroy — RtcEngine.destroy() is invoked via handler.post(RtcEngine::destroy) and not called directly on the main thread. A direct call blocks the UI thread and causes ANR.
IRtcEngineEventHandler callbacks that update UI are wrapped with runOnUIThread(). SDK callbacks arrive on a background thread; touching Views without dispatching to the main thread causes crashes or silent rendering corruption.checkOrRequestPermission() is called before joinChannel(). Joining without the required permissions (RECORD_AUDIO, and CAMERA for video cases) causes a silent failure — no error callback, just no audio/video.setParameters(...) is called during engine initialisation. This is required for Agora backend usage reporting in every case; omitting it causes silent reporting failure even though the app appears to work normally.getPrivateCloudConfig() is null-checked before setLocalAccessPoint() is called. The method returns null on standard (non-private-cloud) builds, so calling setLocalAccessPoint() without the guard causes a NullPointerException.destroy before leaveChannel) — fix teardown to leaveChannel() first, then handler.post(RtcEngine::destroy), and re-test back navigation.runOnUIThread() and re-run the case to verify no thread exceptions.joinChannel() — add checkOrRequestPermission() gate and verify join succeeds only after permission is granted.setParameters(...) or private-cloud null-check — add both safeguards in engine init and re-run the init path once.RtcEngine.destroy() on main thread.leaveChannel() is missing before destroy.IRtcEngineEventHandler callbacks.development
Add a new API example or modify an existing one. Covers both creation and modification scenarios, including dialog class structure, message map registration, and ARCHITECTURE.md updates.
development
Code review for API examples. Ensures examples follow project conventions, handle lifecycle correctly, manage threads safely, and use APIs properly.
development
Add a new API example or modify an existing one. Covers both creation and modification scenarios, including file structure, registration, and ARCHITECTURE.md updates.
development
Code review for API examples. Ensures examples follow project conventions, handle lifecycle correctly, manage threads safely, and use APIs properly.