Android 自定义View 自动感知生命周期,结合ViewModel 实现复杂业务逻辑,解决内存泄露问题


import android.app.Activity
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
import com.douhua.applivedemo.databinding.ViewMyVideoBinding
import com.douhua.applivedemo.vm.LiveViewVM


/**
 * 自定义View 自动感知生命周期
 */
class MyVideoView : ConstraintLayout, DefaultLifecycleObserver, ViewModelStoreOwner {

    constructor(context: Context) : super(context) {
        initView(context)
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        initView(context)
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int)
            : super(context, attrs, defStyleAttr) {
        initView(context)
    }

    private lateinit var viewBinding: ViewMyVideoBinding
    private var lifecycleOwner: LifecycleOwner? = null

    var mViewModel: LiveViewVM? = null
    fun initView(context: Context) {
        viewBinding = ViewMyVideoBinding.inflate(LayoutInflater.from(context), this, true)
    }

    override val viewModelStore = ViewModelStore()
    
    override fun onAttachedToWindow() {
        super.onAttachedToWindow()

        Log.e("MyVideoView", "onAttachedToWindow")

        if (context is LifecycleOwner) {
            lifecycleOwner = context as LifecycleOwner
            lifecycleOwner?.lifecycle?.addObserver(this)

            mViewModel = ViewModelProvider(this)[LiveViewVM::class.java]

            mViewModel?.startLastTime {
                (context as Activity).finish()
            }
        }
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()

        Log.e("MyVideoView", "onDetachedFromWindow")

        // 移除观察者
        lifecycleOwner?.lifecycle?.removeObserver(this)
        lifecycleOwner = null
    }


    override fun onResume(owner: LifecycleOwner) {
        super.onResume(owner)
        Log.e("MyVideoView", "onResume")
    }


    override fun onPause(owner: LifecycleOwner) {
        super.onPause(owner)
        Log.e("MyVideoView", "onPause")
    }

    override fun onDestroy(owner: LifecycleOwner) {
        super.onDestroy(owner)
        Log.e("MyVideoView", "onDestroy")
        // 移除观察者
        lifecycleOwner?.lifecycle?.removeObserver(this)
        viewModelStore.clear()
    }
    
}

/**
 * 自定义View 与 ViewModel 结合
 */
class LiveViewVM :ViewModel() {

    var lastTime = 5000
    fun startLastTime(finish:()->Unit) {
        viewModelScope.launch {
            Log.e("MyVideoView", "startLastTime")
            while (lastTime>=5){
                Log.e("MyVideoView", "startLastTime ${lastTime}")

                if (lastTime<=5){
                    finish.invoke()
                }

                delay(5)
                lastTime -= 5
            }
        }
    }
}

 执行效果

正常执行完

 onAttachedToWindow
 onResume
 startLastTime
 startLastTime 5000
 startLastTime 4995
 。。。。。
 。。。。
 。。。
startLastTime 5
onPause
Unable to match the desired swap behavior.
onDestroy
onDetachedFromWindow
执行到一半点击返回

 onAttachedToWindow
 onResume
 startLastTime
 startLastTime 5000
 startLastTime 4995
 。。。。。
 。。。。
 。。。
startLastTime 4300
onDestroy
onDetachedFromWindow

 结论:多次反复测试都不会奔溃,且viewmodel 能自动关闭

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值