From cadef1850fbc09c6dd5bfa2dccdde2414da5cb26 Mon Sep 17 00:00:00 2001 From: gurevichmi Date: Tue, 17 Jun 2025 05:03:04 +0300 Subject: [PATCH] LoadableImageView bitmap leak fix when view is placed into view pool commit_hash:fe4d0028e8dbaf64b64170f170b9ca2f4d6cad95 --- .../div/core/view2/divs/widgets/DivGifImageView.kt | 6 ++++++ .../div/core/view2/divs/widgets/DivHolderView.kt | 14 +++++++------- .../div/core/view2/divs/widgets/DivImageView.kt | 6 ++++++ .../div/core/view2/divs/widgets/DivRecyclerView.kt | 1 - .../div/core/view2/divs/widgets/DivVideoView.kt | 1 - .../yandex/div/core/widget/LoadableImageView.kt | 12 +++++++++++- 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivGifImageView.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivGifImageView.kt index 4a8051309..b0ce05439 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivGifImageView.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivGifImageView.kt @@ -35,4 +35,10 @@ internal open class DivGifImageView @JvmOverloads constructor( override fun draw(canvas: Canvas) { drawBorderClipped(canvas) { super.draw(it) } } + + override fun release() { + super.release() + super.release() + gifUrl = null + } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivHolderView.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivHolderView.kt index 3984367e2..9ae9c04a2 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivHolderView.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivHolderView.kt @@ -13,6 +13,13 @@ internal interface DivHolderView : DivBorderSupports, var div: T? var bindingContext: BindingContext? + + override fun release() { + super.release() + div = null + bindingContext = null + releaseBorderDrawer() + } } internal class DivHolderViewMixin : DivHolderView, @@ -24,11 +31,4 @@ internal class DivHolderViewMixin : DivHolderView, override var bindingContext: BindingContext? = null override val subscriptions = mutableListOf() - - override fun release() { - super.release() - div = null - bindingContext = null - releaseBorderDrawer() - } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivImageView.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivImageView.kt index fa9382022..a4b4ba3cf 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivImageView.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivImageView.kt @@ -38,4 +38,10 @@ internal open class DivImageView @JvmOverloads constructor( override fun draw(canvas: Canvas) { drawBorderClipped(canvas) { super.draw(it) } } + + override fun release() { + super.release() + super.release() + imageUrl = null + } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivRecyclerView.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivRecyclerView.kt index 2b27c20fd..c9b036438 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivRecyclerView.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivRecyclerView.kt @@ -211,7 +211,6 @@ internal class DivRecyclerView @JvmOverloads constructor( override fun release() { super.release() - releaseBorderDrawer() val currentAdapter = adapter if (currentAdapter is Releasable) { currentAdapter.release() diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivVideoView.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivVideoView.kt index ab67b27f3..cdae031d0 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivVideoView.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/divs/widgets/DivVideoView.kt @@ -36,7 +36,6 @@ internal class DivVideoView @JvmOverloads constructor( playerView.detach() lastPlayer?.release() } - releaseBorderDrawer() } fun getPlayerView(): DivPlayerView? { diff --git a/client/android/div/src/main/java/com/yandex/div/core/widget/LoadableImageView.kt b/client/android/div/src/main/java/com/yandex/div/core/widget/LoadableImageView.kt index e8ecb9247..04544e48f 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/widget/LoadableImageView.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/widget/LoadableImageView.kt @@ -14,6 +14,7 @@ import android.view.ViewGroup import androidx.annotation.CallSuper import com.yandex.div.R import com.yandex.div.core.images.LoadReference +import com.yandex.div.core.view2.Releasable import com.yandex.div.core.view2.divs.widgets.LoadableImage import com.yandex.div.core.view2.drawable.ScaleDrawable import com.yandex.div.internal.widget.AspectImageView @@ -24,7 +25,7 @@ open class LoadableImageView( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : AspectImageView(context, attrs, defStyleAttr), LoadableImage, DivExtendableView { +) : AspectImageView(context, attrs, defStyleAttr), LoadableImage, DivExtendableView, Releasable { @Deprecated("Use imageTransform instead") internal var currentBitmapWithoutFilters: Bitmap? = null @@ -185,6 +186,15 @@ open class LoadableImageView( imageChangeCallback = callback } + override fun release() { + currentBitmapWithoutFilters = null + externalImage = null + sourceDrawable = null + resetImageLoaded() + getLoadingTask()?.cancel(true) + cleanLoadingTask() + } + interface ImageTransformer { fun transform(drawable: Drawable?): Drawable?