Coverage Summary for Class: LayoutLifecycleBindRetry (kr.open.library.simple_ui.xml.ui.layout.base.bind.retry)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| LayoutLifecycleBindRetry |
100%
(3/3)
|
50%
(3/6)
|
82.4%
(14/17)
|
81.2%
(56/69)
|
| LayoutLifecycleBindRetry$retryRunnable$1 |
50%
(1/2)
|
0%
(0/8)
|
12.5%
(1/8)
|
4.4%
(2/45)
|
| LayoutLifecycleBindRetry$start$$inlined$doOnLayout$1 |
0%
(0/2)
|
|
| Total |
57.1%
(4/7)
|
21.4%
(3/14)
|
60%
(15/25)
|
50.9%
(58/114)
|
package kr.open.library.simple_ui.xml.ui.layout.base.bind.retry
import android.view.View
import kr.open.library.simple_ui.xml.extensions.view.doOnLayout
/**
* Retry helper that binds a LifecycleOwner with a layout-first strategy and delayed retries.<br><br>
* 레이아웃 완료 후 우선 바인딩을 시도하고, 실패 시 지연 재시도를 수행하는 헬퍼입니다.<br>
*
* @param view The target view used to post callbacks and check attach state.<br><br>
* 콜백 게시와 attach 상태 확인에 사용하는 대상 View입니다.<br>
* @param callbacks Callback interface that performs the bind operation.<br><br>
* 바인딩 동작을 수행하는 콜백 인터페이스입니다.<br>
* @param maxRetry Maximum number of delayed retry attempts.<br><br>
* 지연 재시도 최대 횟수입니다.<br>
* @param retryDelayMs Delay in milliseconds between retry attempts.<br><br>
* 재시도 간 지연 시간(ms)입니다.<br>
*/
internal class LayoutLifecycleBindRetry(
private val view: View,
private val callbacks: LayoutLifecycleBindRetryCallbacks,
private val maxRetry: Int = 3,
private val retryDelayMs: Long = 50L,
) {
/**
* Tracks how many delayed retries have been attempted.<br><br>
* 지연 재시도 횟수를 추적합니다.<br>
*/
private var retryCount = 0
/**
* Prevents duplicate start calls for the same attach cycle.<br><br>
* 동일한 attach 주기에서 중복 시작을 방지합니다.<br>
*/
private var started = false
/**
* Runnable that performs delayed retry attempts after layout fallback fails.<br><br>
* 레이아웃 우선 시도 실패 후 지연 재시도를 수행하는 Runnable입니다.<br>
*/
private val retryRunnable = object : Runnable {
override fun run() {
if (!started) return
if (!view.isAttachedToWindow) return
val owner = callbacks.bind()
if (owner != null) return
if (retryCount < maxRetry) {
retryCount++
view.postDelayed(this, retryDelayMs)
}
}
}
/**
* Starts binding with a layout-first attempt and then delayed retries.<br><br>
* 레이아웃 우선 시도 후 지연 재시도로 바인딩을 시작합니다.<br>
*/
fun start() {
if (started) return
started = true
view.doOnLayout {
if (!view.isAttachedToWindow) return@doOnLayout
val retryOwner = callbacks.bind()
if (retryOwner != null) return@doOnLayout
retryCount = 0
view.postDelayed(retryRunnable, retryDelayMs)
}
}
/**
* Cancels pending retries and resets internal state.<br><br>
* 대기 중인 재시도를 취소하고 내부 상태를 초기화합니다.<br>
*/
fun cancel() {
view.removeCallbacks(retryRunnable)
retryCount = 0
started = false
}
}