Android timer 参数如何正确设置?

99ANYc3cd6
预计阅读时长 36 分钟
位置: 首页 参数 正文

Handler + postDelayed() (最常用、最灵活)

这是 Android 开发中最基础也是最推荐的方式之一,尤其适用于需要在主线程(UI 线程)上更新界面的场景。

android timer 参数
(图片来源网络,侵删)

核心思想: Handler 是 Android 中用来处理消息和延迟消息的机制,你可以把它想象成一个“任务调度员”。postDelayed() 方法就是告诉这个调度员:“请帮我安排这个任务,并在指定的延迟时间后执行它”。

关键参数:

  1. Runnable r (必需参数)

    • 类型: java.lang.Runnable
    • 描述: 这是你想要在延迟后执行的具体任务,它是一个代码块,通常包含你要执行的逻辑,例如更新 UI、执行某个计算等。
    • 示例:
      new Runnable() {
          @Override
          public void run() {
              // 这里是你要执行的任务,例如更新 TextView
              // textView.setText("时间到!");
          }
      }
  2. long delayMillis (必需参数)

    • 类型: long
    • 描述: 延迟的时间,单位是 毫秒,延迟 1 秒就传入 1000L
    • 示例: 1000 (表示 1 秒后执行)

完整示例代码:

public class MainActivity extends AppCompatActivity {
    private Handler handler = new Handler(Looper.getMainLooper()); // 明确使用主线程的 Handler
    private TextView textView;
    private boolean isTimerRunning = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.textView);
        Button startButton = findViewById(R.id.start_button);
        Button stopButton = findViewById(R.id.stop_button);
        startButton.setOnClickListener(v -> startTimer());
        stopButton.setOnClickListener(v -> stopTimer());
    }
    private void startTimer() {
        if (isTimerRunning) return;
        isTimerRunning = true;
        // 1. 定义任务
        Runnable timerTask = new Runnable() {
            @Override
            public void run() {
                // 更新 UI
                runOnUiThread(() -> { // 虽然Handler在主线程,但为了代码健壮性,可以加上
                    textView.setText("当前时间: " + System.currentTimeMillis());
                });
                // 2. 任务执行完后,再次安排自己执行,实现循环
                if (isTimerRunning) {
                    handler.postDelayed(this, 1000); // 延迟1秒再次执行
                }
            }
        };
        // 3. 第一次执行任务
        handler.postDelayed(timerTask, 1000);
    }
    private void stopTimer() {
        isTimerRunning = false;
        // 移除所有由这个 handler 发送的消息和回调
        handler.removeCallbacksAndMessages(null);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 在 Activity 销毁时,一定要停止 Handler,防止内存泄漏
        handler.removeCallbacksAndMessages(null);
    }
}

优点:

android timer 参数
(图片来源网络,侵删)
  • 与 Android 消息机制完美集成,非常灵活。
  • 可以轻松地在主线程执行 UI 更新。
  • 配合 removeCallbacks() 可以方便地取消定时任务。

缺点:

  • 需要手动管理任务的循环和取消。
  • 如果忘记在 onDestroy 或适当的生命周期中移除回调,可能会导致 内存泄漏

java.util.TimerTimerTask (传统方式)

这是 Java 标准库提供的定时器,不依赖于 Android 框架,它通常用于执行后台的、非 UI 相关的周期性任务。

核心思想: Timer 是一个调度器,TimerTask 是一个实现了 Runnable 接口的任务,你将 TimerTask 提交给 Timer,并指定执行时间。

关键参数 (以 schedule 方法为例):

  1. TimerTask task (必需参数)

    android timer 参数
    (图片来源网络,侵删)
    • 类型: java.util.TimerTask
    • 描述: 你要执行的具体任务,需要继承 TimerTask 并重写 run() 方法。
  2. long delay (必需参数)

    • 类型: long
    • 描述: 首次执行前的 延迟时间,单位是毫秒。
  3. long period (必需参数)

    • 类型: long
    • 描述: 周期,即两次执行之间的时间间隔,单位是毫秒,这个参数使得任务可以重复执行。

完整示例代码:

import java.util.Timer;
import java.util.TimerTask;
public class TimerExample {
    private Timer timer;
    private TimerTask timerTask;
    public void startTimer() {
        if (timer != null) {
            timer.cancel();
        }
        timer = new Timer();
        timerTask = new TimerTask() {
            @Override
            public void run() {
                // 注意:这个 run() 方法运行在后台线程,不能直接操作 UI!
                // 可以在这里进行网络请求、文件读写等。
                System.out.println("TimerTask executed on background thread: " + System.currentTimeMillis());
            }
        };
        // 参数1: 任务
        // 参数2: 首次执行的延迟时间 (毫秒)
        // 参数3: 执行周期 (毫秒)
        timer.schedule(timerTask, 1000, 2000); // 1秒后开始,每2秒执行一次
    }
    public void stopTimer() {
        if (timer != null) {
            timer.cancel(); // 取消整个定时器
            timer.purge();  // 清理已取消的任务
            timer = null;
        }
    }
}

优点:

  • 简单直接,适合纯 Java 环境。
  • 对于后台任务,逻辑清晰。

缺点:

  • 不能直接更新 UI,因为它运行在后台线程。
  • 如果任务执行时间超过了 period,可能会导致任务堆积。
  • 不如 Handler 方式与 Android 生命周期结合紧密。

ScheduledExecutorService (现代、强大的后台任务调度器)

这是 Java 并发包 (java.util.concurrent) 提供的更现代、更强大的调度工具,它是 Timer 的升级版,功能更强大,性能更好。

核心思想: 创建一个线程池,然后向这个线程池提交“延迟执行”或“周期性执行”的任务。

关键参数 (以 scheduleAtFixedRate 方法为例):

  1. Runnable command (必需参数)

    • 类型: java.lang.Runnable
    • 描述: 你要执行的任务。
  2. long initialDelay (必需参数)

    • 类型: long
    • 描述: 首次执行前的 初始延迟,单位是 纳秒 (但通常用毫秒)。
  3. long period (必需参数)

    • 类型: long
    • 描述: 周期,即两次执行开始时间之间的时间间隔,单位是 纳秒 (但通常用毫秒)。

完整示例代码:

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ExecutorTimerExample {
    private ScheduledExecutorService scheduledExecutorService;
    public void startTimer() {
        // 创建一个单线程的调度器
        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        // 定义任务
        Runnable task = () -> {
            // 运行在后台线程,不能直接操作 UI
            System.out.println("ExecutorService task executed: " + System.currentTimeMillis());
        };
        // 参数1: 任务
        // 参数2: 初始延迟 (秒)
        // 参数3: 周期 (秒)
        // 参数4: 时间单位
        scheduledExecutorService.scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS);
    }
    public void stopTimer() {
        if (scheduledExecutorService != null && !scheduledExecutorService.isShutdown()) {
            scheduledExecutorService.shutdown(); // 优雅关闭,会执行完当前任务
            // scheduledExecutorService.shutdownNow(); // 立即关闭,尝试中断正在执行的任务
        }
    }
}

优点:

  • 功能强大,支持更复杂的调度策略。
  • 基于线程池,性能和可靠性优于 Timer
  • 可以更好地控制线程的生命周期。

缺点:

  • 同样,不能直接更新 UI
  • API 比 Handler 稍复杂。

CountDownTimer (倒计时专用)

如果你需要的是一个倒计时功能(验证码倒计时、游戏倒计时),CountDownTimer 是最佳选择。

核心思想: Android SDK 提供的专门用于倒计时的工具类,内部已经用 Handler 实现,使用起来非常方便。

关键参数:

  1. long millisInFuture (必需参数)

    • 类型: long
    • 描述: 倒计时的总时长,单位是 毫秒
  2. long countDownInterval (必需参数)

    • 类型: long
    • 描述: 倒计时的 间隔,单位是 毫秒,系统会每隔这个时间调用一次 onTick() 方法,传入 1000 表示每秒更新一次。

关键方法 (而非参数):

  • onTick(long millisUntilFinished): 每隔 countDownInterval 毫秒被调用一次,参数 millisUntilFinished 是剩余的毫秒数。
  • onFinish(): 倒计时结束时被调用一次。

完整示例代码:

public class MainActivity extends AppCompatActivity {
    private TextView countdownTextView;
    private CountDownTimer countDownTimer;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        countdownTextView = findViewById(R.id.countdown_text);
        Button startButton = findViewById(R.id.start_countdown_button);
        startButton.setOnClickListener(v -> startCountdown());
    }
    private void startCountdown() {
        // 如果已有计时器在运行,先取消它
        if (countDownTimer != null) {
            countDownTimer.cancel();
        }
        // 参数1: 总时长 (10秒 = 10000毫秒)
        // 参数2: 间隔 (1秒 = 1000毫秒)
        countDownTimer = new CountDownTimer(10000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                // 更新 UI
                countdownTextView.setText("剩余: " + (millisUntilFinished / 1000) + " 秒");
            }
            @Override
            public void onFinish() {
                // 倒计时结束
                countdownTextView.setText("倒计时结束!");
            }
        }.start(); // 别忘了调用 start() 方法
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (countDownTimer != null) {
            countDownTimer.cancel();
        }
    }
}

优点:

  • API 设计非常符合倒计时场景,使用极其简单。
  • 内部处理了线程问题,可以直接在 onTickonFinish 中更新 UI。
  • 自动管理,不易出错。

缺点:

  • 仅适用于倒计时场景,不能用于正计时。

协程 (Coroutines) - 现代 Android 开发首选

对于现代 Android 开发(Kotlin),协程是处理异步任务(包括定时器)的官方推荐方式,它代码更简洁,可读性更高,且能更好地处理生命周期。

核心思想: 通过 delay() 函数来实现延迟,而不是传统的回调,代码看起来像同步代码,但执行过程是异步的。

关键参数/函数:

  1. delay(timeMillis: Long) (核心函数)
    • 类型: 挂起函数
    • 描述: 暂协当前协程指定的毫秒数,它不会阻塞线程,只是让出线程的执行权。

完整示例代码 (使用 lifecycleScope):

// 在 Activity 或 Fragment 中
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
    private val textView: TextView by lazy { findViewById(R.id.textView) }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Button startButton).setOnClickListener {
            startTimer()
        }
    }
    private fun startTimer() {
        // lifecycleScope 会自动在 Activity/Fragment 销毁时取消协程,防止内存泄漏
        lifecycleScope.launch {
            repeat(10) { i -> // 重复10次
                delay(1000) // 延迟1秒
                textView.text = "计时: ${i + 1}"
            }
            textView.text = "计时完成!"
        }
    }
}

优点:

  • 代码简洁优雅,结构清晰,易于维护。
  • 内置生命周期管理,使用 lifecycleScopeviewModelScope 可以自动取消任务,避免内存泄漏。
  • 不阻塞主线程,性能好。
  • 可以轻松组合复杂的异步逻辑。

缺点:

  • 需要学习 Kotlin 协程的概念,对于 Java 开发者有一定门槛。

总结与选择建议

方法 核心参数 适用场景 线程 优点 缺点
Handler + postDelayed Runnable, delayMillis UI 更新、正计时 主线程 灵活,与Android框架集成度高 需手动管理,易内存泄漏
java.util.Timer TimerTask, delay, period 简单后台任务 后台线程 Java标准,简单 不能更新UI,功能有限
ScheduledExecutorService Runnable, initialDelay, period 复杂后台任务调度 后台线程 功能强大,性能好,线程池管理 不能更新UI,API稍复杂
CountDownTimer millisInFuture, countDownInterval 倒计时 (如验证码) 主线程 API专为倒计时设计,简单易用 仅限倒计时
协程 (Coroutines) delay(timeMillis) 现代Android开发 (所有异步) 主/后台均可 代码简洁,生命周期安全,是未来趋势 需要学习Kotlin协程

如何选择?

  • 如果要在界面上做倒计时(如60秒重发验证码):首选 CountDownTimer
  • 如果要在界面上做正计时(如秒表、游戏计时):首选 Handler + postDelayed()
  • 如果要做纯后台的、非UI的周期性任务(如轮询服务器):首选 ScheduledExecutorService
  • 如果你正在用 Kotlin 开发新项目:强烈推荐使用 协程,它是处理所有异步(包括定时器)任务的最佳实践。
-- 展开阅读全文 --
头像
苏泊尔全智能电压力锅价格多少钱?
« 上一篇 01-04
东芝Satellite A100拆机步骤详解?
下一篇 » 01-04

相关文章

取消
微信二维码
支付宝二维码

最近发表

标签列表

目录[+]