awa 泠云酱好可爱!!! - #10
Conversation
📝 WalkthroughWalkthrough本次变更为前台监控增加专用后台线程和反射缓存,修复 Changes运行时稳定性与模块兼容性
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant XposedHook
participant ForegroundAppMonitor
participant HandlerThread
participant AndroidSystem
XposedHook->>ForegroundAppMonitor: 恢复钩子读取前台包名和活动名
ForegroundAppMonitor->>HandlerThread: 投递心跳、查询和自定义操作
HandlerThread->>AndroidSystem: 查询应用信息并注册锁屏接收器
AndroidSystem-->>HandlerThread: 返回查询结果或广播回调
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
app/src/main/java/io/github/recloudstudio/sleepyxposed/ForegroundAppMonitor.kt (1)
225-242: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win缓存缺失字段时不要返回
null。
ConcurrentHashMap.computeIfAbsent在 mapping 函数返回null时不会保存映射。当前代码不会缓存缺失字段。缺少 OEM 字段时,每次 activity resume 都会再次遍历继承链。使用非空哨兵值表示字段缺失,或缓存一个非空包装类型。这样才可以实现负缓存。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/src/main/java/io/github/recloudstudio/sleepyxposed/ForegroundAppMonitor.kt` around lines 225 - 242, Update the fieldCache logic in ForegroundAppMonitor around the computeIfAbsent call so missing fields are represented by a non-null sentinel or wrapper and therefore cached by ConcurrentHashMap. Ensure field lookup still traverses the superclass chain once and callers correctly interpret the sentinel as an absent field.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@app/src/main/java/io/github/recloudstudio/sleepyxposed/MediaStatusMonitor.kt`:
- Around line 248-249: 在读取线程处理逻辑中检查 readerThread.join(...) 返回后的
readerThread.isAlive 状态;若线程仍存活,记录读取超时并立即返回 null,禁止继续调用
outputRef.toString(),仅在线程结束后解析完整输出。
- Around line 222-239: 在 MediaStatusMonitor 中负责读取 dumpsys 输出的 readerThread 逻辑里,为
outputRef 设置明确的最大输出字节数;读取过程中一旦达到上限,立即停止读取并销毁子进程,随后让调用流程返回
null,禁止继续解析不完整的输出。保留正常结束和超时关闭流的现有处理。
---
Nitpick comments:
In
`@app/src/main/java/io/github/recloudstudio/sleepyxposed/ForegroundAppMonitor.kt`:
- Around line 225-242: Update the fieldCache logic in ForegroundAppMonitor
around the computeIfAbsent call so missing fields are represented by a non-null
sentinel or wrapper and therefore cached by ConcurrentHashMap. Ensure field
lookup still traverses the superclass chain once and callers correctly interpret
the sentinel as an absent field.
🪄 Autofix
❌ Autofix failed (check again to retry)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 54e75374-ee42-4b1b-b389-9f79c0400c81
📒 Files selected for processing (4)
app/proguard-rules.proapp/src/main/java/io/github/recloudstudio/sleepyxposed/ForegroundAppMonitor.ktapp/src/main/java/io/github/recloudstudio/sleepyxposed/MediaStatusMonitor.ktapp/src/main/java/io/github/recloudstudio/sleepyxposed/ui/SleepyApp.kt
| val outputRef = StringBuilder() | ||
| val reader = process.inputStream | ||
| val readerThread = | ||
| Thread { | ||
| try { | ||
| BufferedReader(InputStreamReader(reader)).use { br -> | ||
| val buf = CharArray(4096) | ||
| while (true) { | ||
| val n = br.read(buf) | ||
| if (n < 0) break | ||
| outputRef.append(buf, 0, n) | ||
| } | ||
| } | ||
| } catch (_: IOException) { | ||
| // Stream closed because we destroyed the process on timeout; ignore. | ||
| } | ||
| } | ||
| .also { it.isDaemon = true; it.start() } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
限制 dumpsys 输出的最大缓存量。
outputRef 没有容量上限。dumpsys media_session 输出越大,system_server 的堆分配越大。此变更消除了管道背压,但把风险转移为无界内存增长。
设置最大输出大小。达到上限时停止读取、销毁子进程并返回 null,不要继续解析不完整输出。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/src/main/java/io/github/recloudstudio/sleepyxposed/MediaStatusMonitor.kt`
around lines 222 - 239, 在 MediaStatusMonitor 中负责读取 dumpsys 输出的 readerThread
逻辑里,为 outputRef 设置明确的最大输出字节数;读取过程中一旦达到上限,立即停止读取并销毁子进程,随后让调用流程返回
null,禁止继续解析不完整的输出。保留正常结束和超时关闭流的现有处理。
| readerThread.join(TimeUnit.SECONDS.toMillis(DUMPSYS_TIMEOUT_SECONDS)) | ||
| val output = outputRef.toString() |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
仅在读取线程结束后解析输出。
readerThread.join(...) 有超时,但代码未检查 readerThread.isAlive。如果读取线程仍在追加内容,outputRef.toString() 会与 StringBuilder.append() 并发执行,并且可能解析部分或不一致的媒体状态。
如果 join 超时,记录读取超时并返回 null。不要读取仍在被写入的 outputRef。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/src/main/java/io/github/recloudstudio/sleepyxposed/MediaStatusMonitor.kt`
around lines 248 - 249, 在读取线程处理逻辑中检查 readerThread.join(...) 返回后的
readerThread.isAlive 状态;若线程仍存活,记录读取超时并立即返回 null,禁止继续调用
outputRef.toString(),仅在线程结束后解析完整输出。
|
The branch was updated while autofix was in progress. Please try again. |
|
The branch was updated while autofix was in progress. Please try again. |
|
呜哇不好好起标题被泠云酱责备了… |
1.新增了一个后台进程做处理,防止system_server 主线程被占用的情况下,系统直接卡死,最终触发 Watchdog 杀掉 system_server
2.缓存进程的名字,在15s的期间不会完整再走一遍扫描和检查之类的,或许能减少些资源占用(?
3.减少了管道死锁的风险,防止媒体状态太多阻塞了,导致全部爆炸!!
4.ModuleHooks.kt我寻思也没用到啊,哪个啥子ai写的,滚出去滚出去
总结:提高系统的稳定性,优化系统的流畅度()
This change is
Summary by CodeRabbit
性能与稳定性
兼容性