From 041d367f7daa87e7130de6e7b37fd798a863f996 Mon Sep 17 00:00:00 2001 From: Sadturtleman Date: Tue, 3 Nov 2026 00:28:15 +0900 Subject: [PATCH] =?UTF-8?q?fix(observability):=20JankTracker=20=EC=9D=98?= =?UTF-8?q?=20=ED=94=84=EB=A0=88=EC=9E=84=C2=B7=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=A0=84=ED=99=98=20=EC=B2=98=EB=A6=AC=EB=A5=BC=20=EC=A7=81?= =?UTF-8?q?=EB=A0=AC=ED=99=94=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit onFrame 은 FrameMetrics HandlerThread, onScreenChanged 는 메인 스레드에서 호출되는데 같은 ArrayList·카운터를 동기화 없이 바꿔 closeWindow 의 정렬이 NPE·IndexOutOfBounds 로 죽었다. Co-Authored-By: Claude Opus 5.5 --- .../com/ruleup/android_ruleup/observability/JankTracker.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/com/ruleup/android_ruleup/observability/JankTracker.kt b/app/src/main/java/com/ruleup/android_ruleup/observability/JankTracker.kt index 35aad5cda..cda012013 100644 --- a/app/src/main/java/com/ruleup/android_ruleup/observability/JankTracker.kt +++ b/app/src/main/java/com/ruleup/android_ruleup/observability/JankTracker.kt @@ -30,13 +30,17 @@ class JankTracker // 창 하나(5초 × 60fps ≈ 300개) 분량. private val durationsMillis = ArrayList(INITIAL_SAMPLES) + // onFrame 은 FrameMetrics HandlerThread, onScreenChanged 는 메인 스레드에서 온다. 상태를 같이 쓰므로 직렬화한다. + /** 화면 전환 직전에 호출한다. */ + @Synchronized fun onScreenChanged() { if (total > 0) closeWindow((lastFrameNanos - windowStartNanos) / NANOS_PER_MILLI) windowStartNanos = 0L lastFrameNanos = 0L } + @Synchronized fun onFrame(frame: FrameData) { val startNanos = frame.frameStartNanos if (windowStartNanos == 0L) {