ListView ANR during dynamic-height recycling on Android 10+
0 reputation · 19 Mar 2024, 00:33 UTC
0 reputation · 19 Mar 2024, 00:33 UTC
Profiling a Titanium 10.x Android app reveals Application Not Responding (ANR) reports when a ListView with 500+ rows uses custom templates set to height: Ti.UI.SIZE. The goal is to quantify whether the ANR originates from repeated measure/layout passes that defeat RecyclerView view-holder recycling, or from JavaScript execution spikes after the V8 9.4 upgrade changed JIT heuristics.
Constraints include the inability of ti profile --cpu alone to correlate JS function timings with native main-thread stalls, and the cross-platform divergence where iOS UITableView recycling behaves differently than Android RecyclerView. Memory growth observed via ti profile --heap snapshots may not capture native view-holder allocation pressure.
Which profiling combination reliably isolates the recycling failure: Chrome DevTools timeline, Android Studio CPU profiler main-thread trace, or Ti.API.info timestamps in the template's postlayout event? Does enforcing fixed row heights eliminate the ANR without redesigning the data model? How can developers verify view-holder reuse counts on Android without modifying the Titanium SDK source?
The most likely explanation is that Ti.UI.SIZE forces a full onMeasure/onLayout pass for every row during binding. With 500+ variably sized rows, scrolling multiplies these native measure passes on the main thread, triggering ANRs. This is the established pattern for Titanium Android ListViews with dynamic heights.
Likely explanation: Dynamic-height templates defeat view-holder recycling because each bind requires a fresh measurement. No single JS‑only tool can isolate this; the Android Studio CPU profiler (or Perfetto/systrace) on the main thread is the primary device for separating native layout time from V8 execution time.
Confirmed facts from the research brief: Ti.UI.SIZE row heights force a measure pass per row as data binds, multiplying onMeasure/onLayout work. Android Studio CPU profiler (or Perfetto/systrace) shows whether samples cluster in measure/layout versus V8/JS. Fixed row heights (dp values) typically eliminate or drastically reduce the ANR without data-model changes. Ti.API.info timestamps in postlayout handlers are a low-cost complement: log per‑row bind duration and count events per scroll to spot recycling failure.
Assumption: This diagnosis attributes the ANR to main‑thread measure/layout pressure from dynamic row heights; the V8 9.4 JIT heuristic change is speculative and requires CPU profiler verification.
onMeasure, onLayout, or V8/JS functions.Ti.API.info logs inside the template's postlayout event to record timestamps and row indices. Count how many events fire during a single scroll gesture.height: 80dp). Replay the same scroll. If the ANR disappears, the dynamic‑height measure hypothesis is confirmed.If the ANR persists after fixing row heights, consider whether the ListView uses a native Android RecyclerView wrapper or a pure Titanium JS implementation, as SDK version and binding architecture affect which profiler signals appear.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.