Fix memory leak in timers

commit_hash:0c54576ac889e720ca8151d6d104c7a72a8056c9
This commit is contained in:
grechka62
2024-10-22 09:03:46 +03:00
parent 211daa22ec
commit a2ee68b445
3 changed files with 25 additions and 20 deletions
+1
View File
@@ -2,6 +2,7 @@
# Android Client:
* `variable_triggers` defined locally are now attached only when they are within an active `state`.
* Fixed memory leak in timers.
# iOS Client:
* Added DivSubmitAction which allows to submit data from container. Can be used while creating forms with DivKit.
@@ -13,8 +13,6 @@ internal class DivTimerEventDispatcher(
private var parentTimer: Timer? = null
private var div2View: Div2View? = null
fun getTimerController(id: String): TimerController? {
return if (activeTimerIds.contains(id)) {
timerControllers[id]
@@ -33,9 +31,7 @@ internal class DivTimerEventDispatcher(
timerControllers
.filter { !ids.contains(it.key) }
.values
.forEach { timerController ->
timerController.onDetach()
}
.forEach { it.reset() }
activeTimerIds.clear()
@@ -49,25 +45,26 @@ internal class DivTimerEventDispatcher(
}
fun onAttach(view: Div2View) {
val newParentTimer = Timer()
parentTimer = newParentTimer
div2View = view
var newParentTimer: Timer? = null
activeTimerIds.forEach { id ->
timerControllers[id]?.onAttach(view, newParentTimer)
val controller = timerControllers[id] ?: return@forEach
if (controller.isAttachedToView(view)) return@forEach
(newParentTimer ?: createParentTimer().also { newParentTimer = it }).let {
controller.onAttach(view, it)
}
}
}
fun onDetach(view: Div2View) {
/*
* Fix bug, when div2view in recycler view.
* In recycler during bind first called attach for new view, than detach for old one.
*/
if (div2View != view) return
private fun createParentTimer() = Timer().also {
parentTimer?.cancel()
parentTimer = it
}
fun onDetach(view: Div2View) {
timerControllers.values.forEach { timerController ->
timerController.onDetach()
timerController.onDetach(view)
}
parentTimer?.cancel()
@@ -41,8 +41,8 @@ internal class TimerController(
private fun updateTimer() {
ticker.update(
divTimer.duration.evaluate(expressionResolver).toLong(),
divTimer.tickInterval?.evaluate(expressionResolver)?.toLong()
divTimer.duration.evaluate(expressionResolver),
divTimer.tickInterval?.evaluate(expressionResolver)
)
}
@@ -61,7 +61,12 @@ internal class TimerController(
}
}
fun onDetach() {
fun onDetach(view: Div2View?) {
if (view != div2View) return
reset()
}
fun reset() {
div2View = null
ticker.saveState()
@@ -70,6 +75,8 @@ internal class TimerController(
savedForBackground = true
}
fun isAttachedToView(view: Div2View) = view == div2View
fun applyCommand(command: String) {
when (command) {
START_COMMAND -> ticker.start()