TemplateRateLimiter
Rate limiter for Android Auto template invalidation calls.
Android Auto has recommended update frequency limits to prevent UI lag and ANRs. This class provides throttling with trailing edge guarantee - ensuring the final state is always rendered even if intermediate updates are skipped.
Problem Solved
During active navigation, guidance state updates can occur multiple times per second (maneuver changes, distance updates, ETA updates). Calling invalidate() for each update overwhelms the Android Auto host and can cause:
UI lag and stuttering
ANRs (Application Not Responding)
Excessive template rebuilds
Solution: Throttle with Trailing Edge
This limiter uses a "throttle with trailing edge" pattern:
Immediate execution: First call executes immediately
Throttling: Subsequent calls within the cooldown period are skipped
Trailing edge: If calls were skipped, one final call executes after cooldown
This ensures:
Responsive initial updates (no delay on first call)
Limited update frequency (respects host capabilities)
Final state consistency (trailing edge guarantees last state is rendered)
Usage
class MyScreen : Screen(carContext) {
private val rateLimiter = TemplateRateLimiter(
scope = screenScope,
minIntervalMs = 100L,
tag = "MyScreen"
)
fun onStateChanged() {
rateLimiter.requestInvalidate { invalidate() }
}
override fun onDestroy(owner: LifecycleOwner) {
rateLimiter.cancel()
}
}Thread Safety
This class uses AtomicLong for timestamp tracking and coroutine-based scheduling, making it safe for concurrent access from multiple threads.
Parameters
CoroutineScope for scheduling delayed invalidation (should be screen-scoped)
Minimum interval between invalidate calls in milliseconds. Recommended: 100-200ms for navigation, 300-500ms for less critical screens.
Logging tag for debug output