欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

在 kotlin 中实现定时器的两种方法

最编程 2024-07-09 21:58:54
...
一、viewModel+自定义接口的方式实现

注意点:viewModel中不要传入context的相关内容,容易内存泄露,如果需要上下文对象,可以继承ViewModel类的子类AndroidViewModel类,而不是ViewModel类.

class TimeViewModel:ViewModel() {
    private lateinit var timer:Timer
    private var currentSecond=0

    fun startTimer(){
        timer=Timer()
        currentSecond=0

        val timerTask=object :TimerTask(){
            override fun run() {
                currentSecond++
                if (onTimeChangeListener!=null){
                    onTimeChangeListener.onTimeChanged(currentSecond)
                }
            }
        }
        timer.schedule(timerTask,1000,1000)
    }
    interface OnTimeChangeListener{
        fun onTimeChanged(second:Int)
    }
    private lateinit var onTimeChangeListener: OnTimeChangeListener
    fun setOnTimeChangeListener(onTimeChangeListener: OnTimeChangeListener){
        this.onTimeChangeListener=onTimeChangeListener
    }

    override fun onCleared() {
        super.onCleared()
        timer.cancel()
    }
}

activity或者fragment中的调用:

private fun timeListener(){
        val timeViewModel= ViewModelProvider(this)[TimeViewModel::class.java]

        timeViewModel.setOnTimeChangeListener(object :TimeViewModel.OnTimeChangeListener{
            override fun onTimeChanged(second: Int) {
                activity?.runOnUiThread {
                    binding.textviewTime.text="TIME:$second"
                }
            }

        })
        timeViewModel.startTimer()
    }
二、viewModel+LiveData的实现

注意区分一下setValue:只能用于主线程,
postValue:可以用在主线程,也可以子线程

class TimeWithLivedataViewModel:ViewModel() {
    private lateinit var timer: Timer
    private var currentSecond=0

    private  var second:MutableLiveData<Int>  = MutableLiveData()
    fun getCurrentSecond():MutableLiveData<Int>{
        return second
    }
    
    fun startTimer(){
        timer=Timer()
        currentSecond=0
        val timerTask=object :TimerTask(){
            override fun run() {
                currentSecond++
                second.postValue(currentSecond)
            }
        }
        timer.schedule(timerTask,1000,1000)
    }
}

liveData.observe()方法对Livedata包装的数据进行观察,反过来,当我们需要修改livedata包装的数据的时候,可以通过postValue/setValue来完成,这个方式只是会插入当前的数据中,不会重新开始执行,如果想重新开始,则需要修改viewmodel中的初始值.

  private fun timeLiveData(){
        val timeWithLivedataViewModel=ViewModelProvider(this)[TimeWithLivedataViewModel::class.java]
        val  liveData=timeWithLivedataViewModel.getCurrentSecond()
        liveData.observe(requireActivity()){second->
            binding.textviewTime.text="TIME:$second"
        }

        binding.btnTime.setOnClickListener {
            liveData.postValue(0)
//            timeWithLivedataViewModel.currentSecond=0

        }
        timeWithLivedataViewModel.startTimer()

    }

此外,livedata的observe方法的最后一行代码可以看出,livedata可以感知页面的生命周期,获取页面的状态


截屏2023-03-10 15.51.30.png

推荐阅读