【工具类】定时器-Workmanager,Timer,AlarmManager,Handler,Thread,协程倒计时

431 阅读2分钟

定时器

一、基本知识

1、基本实现方案: Timer,AlarmManager,Handler,Thread

2、参考文章

  1. Android实现定时器的几种方法
  2. Android 定时器 - 掘金 (juejin.cn)

3、android alarm timer 哪个好_百度知道 (baidu.com)

4、AlarmManger应该可以被WorkManager取代,因为他底层低版本用Alarm实现,Handler的话Acivity被销毁的时候就无效了,放在Service的话两说,workManager做说明可能更好;

1、Timer

1、基本说明

1、性质:Java中的API,本质上调用了Handler,且耦合较高;据说特别耗电;不建议使用。 2、使用样例:java自定义定时任务出发时间

2、 AlarmManager【要用的话多查点资料】

1、性质: Alarm机制是Android提供的。 Timer并不太适用于那些需要长期在后台运行的定时任务。而Alarm则具有唤醒CPU的功能(非唤醒屏幕), 它可以保证在大多数情况下需要执行定时任务的时候CPU都能正常工

3、 Handler

1、性质:安卓的Doze模式,尽可能的节约用电。使用Handler定时,在程序后台运行且手机锁屏的情况下,handler定时可能会失效,但是AlarmManager就不一样,在程序后台运行且手机手机锁屏的情况下,定时也是基本上准确的。

2、被弃用的构造方法:Android Handler被弃用,那么以后怎么使用Handler,或者类似的功能_handle弃用

4、Thread

1、通过Thread做循环,通过handler更新UI,个人感觉不如直接用Handler。

5、WorkManager

1、新架构组件: WorkManager

2、 Android WorkManager入门与实践

6、协程倒计时法 感觉像是Handler的上位替代

1、 popWindow没有生命周期 findViewTreeLifecycleOwner为空,DialogFragment不为空,Dialog不太清楚;

2、 全局handler倒计时配合recycleView设置监听的方式,给个回调,啥地方调用啥地方监听;

3、参考:设计 repeatOnLifecycle API 背后的故事 - 掘金 (juejin.cn)

4、通过协程结合SparseArray可以实现多个场景分别计时;

binding.root.findViewTreeLifecycleOwner()?.lifecycleScope?.launch{
    binding.root.findViewTreeLifecycleOwner()?.lifecycle?.repeatOnLifecycle(Lifecycle.State.STARTED){
        delay(1000)
        
    }
}
  1. 样例2
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import kotlinx.coroutines.*


class TimerFragment : Fragment() {

    private lateinit var timerTextView: TextView
    private var job: Job? = null

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_timer, container, false)
        timerTextView = view.findViewById(R.id.timerTextView)
        return view
    }

    override fun onResume() {
        super.onResume()
        startTimer()
    }

    override fun onPause() {
        super.onPause()
        stopTimer()
    }

    private fun startTimer() {
        job = CoroutineScope(Dispatchers.Main).launch {
            var seconds = 0
            while (true) {
                val hours = seconds / 3600
                val minutes = (seconds % 3600) / 60
                val secs = seconds % 60
                timerTextView.text = String.format("%02d:%02d:%02d", hours, minutes, secs)
                delay(1000)
                seconds++
            }
        }
    }

    private fun stopTimer() {
        job?.cancel()
    }
}

样例3、生命周期期间每隔1s更新一次

lifecycleScope.launch {
    while (isActive) {  // 当协程处在活跃状态时循环
        val now = Date()
        val sdf = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
        val formattedTime = sdf.format(now)

        tvDrinkTip.text = formattedTime  // 更新TextView内容

        delay(1000) // 等待一秒
    }
}