GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - xesam/Android-Timer: 一个轻量级的Android计时器库,提供 AndroidTimer、CountDownTimer、AndroidTick 三个相互独立的核心组件,支持开始/暂停/恢复/停止。

BranchesTags
Open more actions menu

Latest commit

 

History

48 Commits
48 Commits

Folders and files

NameName
Last commit message
Last commit date
android-timer-kt
android-timer-kt
 
 
android-timer
android-timer
 
 
app
app
 
 
config
config
 
 
gradle
gradle
 
 
.gitignore
.gitignore
 
 
AGENTS.md
AGENTS.md
 
 
AndroidTimer.jpg
AndroidTimer.jpg
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 
build.gradle
build.gradle
 
 
gradle.properties
gradle.properties
 
 
gradlew
gradlew
 
 
gradlew.bat
gradlew.bat
 
 
settings.gradle
settings.gradle
 
 

Repository files navigation

AndroidTimer

一个轻量级的Android计时器库,提供 AndroidTimer、CountDownTimer、AndroidTick 三个相互独立的核心组件,前两者支持灵活的状态管理。

AndroidTimer

目录

  1. 快速开始
    • 1.1 添加依赖
    • 1.2 基本使用
  2. API 文档
    • 2.1 AndroidTimer
    • 2.2 CountDownTimer
    • 2.3 AndroidTick
    • 2.4 配置选项
    • 2.5 IntervalChangeMode
  3. 状态管理
  4. 开发
  5. Kotlin API(android-timer-kt)
  6. 变更记录
  7. 许可证
  8. 联系方式

1. 快速开始

1.1 添加依赖

在模块目录的 build.gradle 文件中添加:

1.1.1 Java 项目

dependencies {
    implementation 'io.github.xesam:android-timer:0.4.3'
}

1.1.2 Kotlin 项目(含 Flow API)

dependencies {
    implementation 'io.github.xesam:android-timer-kt:0.4.3'
}

android-timer-kt 已通过 api 依赖传递 android-timer 与 kotlinx-coroutines,无需重复声明。

1.2 基本使用

1.2.1 AndroidTimer(周期性计时器)

// 创建计时器:每1000ms触发一次onTick
AndroidTimer timer = new AndroidTimer(1000L) {
            @Override
            protected void onTick(long millisFly) {
                Log.d("Timer", "Elapsed: " + millisFly + "ms");
            }

            @Override
            protected void onStart(long millisFly) {
                Log.d("Timer", "Started at: " + millisFly + "ms");
            }

            @Override
            protected void onPause(long millisFly) {
                Log.d("Timer", "Paused at: " + millisFly + "ms");
            }

            @Override
            protected void onResume(long millisFly) {
                Log.d("Timer", "Resumed from: " + millisFly + "ms");
            }

            @Override
            protected void onCancel(long millisFly) {
                Log.d("Timer", "Cancelled at: " + millisFly + "ms");
            }
        };

// 启动
timer.start();

// 暂停
timer.pause();

// 恢复
timer.resume();

// 取消
timer.cancel();

1.2.2 CountDownTimer(倒计时器)

// 创建倒计时器:10秒倒计时,每100ms更新一次
CountDownTimer countDownTimer = new CountDownTimer(10000L, 100L) {
            @Override
            protected void onStart(long millisUntilFinished) {
                // 倒计时开始
                Log.d("CountDown", "Started: " + millisUntilFinished + "ms remaining");
            }

            @Override
            protected void onTick(long millisUntilFinished) {
                // 倒计时进行中
                Log.d("CountDown", "Remaining: " + millisUntilFinished + "ms");
            }

            @Override
            protected void onPause(long millisUntilFinished) {
                // 倒计时暂停
                Log.d("CountDown", "Paused with " + millisUntilFinished + "ms remaining");
            }

            @Override
            protected void onResume(long millisUntilFinished) {
                // 倒计时恢复
                Log.d("CountDown", "Resumed with " + millisUntilFinished + "ms remaining");
            }

            @Override
            protected void onCancel(long millisUntilFinished) {
                // 倒计时取消
                Log.d("CountDown", "Cancelled with " + millisUntilFinished + "ms remaining");
            }

            @Override
            protected void onFinish(long millisDuration) {
                // 倒计时完成
                Log.d("CountDown", "Finished!");
            }
        };
// 启动
countDownTimer.start();

// 暂停
countDownTimer.pause();

// 恢复
countDownTimer.resume();

// 取消
countDownTimer.cancel();

1.2.3 AndroidTick(单次延迟回调)

一个轻量级的单次延迟工具。tick() 触发一次延迟任务,回调触发后自动结束。

// 创建:500ms 后触发一次回调
AndroidTick tick = new AndroidTick(500L) {
    @Override
    protected void onTick(AndroidTick thisInstance, int count) {
        // count 为累计触发次数
        Log.d("Tick", "Triggered " + count + " times");
    }
};

// 触发延迟任务(若已有待执行任务,此次调用被静默忽略)
tick.tick();

// 取消上一次任务并重新计时
tick.tick(true);

// 取消待执行的回调
tick.cancel();

构造参数 millisDelay 必须大于 0,否则抛出 IllegalArgumentException。可通过 isRunning() 查询是否有待执行任务。

典型场景:搜索框防抖(用户停止输入后 500ms 才发起请求)、延迟隐藏 Toast。

2. API 文档

2.1 AndroidTimer

2.1.1 构造函数

AndroidTimer(long interval)

AndroidTimer(long interval, AndroidTimer.Option option)

interval 必须大于 0,否则抛出 IllegalArgumentException。省略 option 时使用默认配置(tickWhenStart = false)。

2.1.2 方法

  • start(): 启动计时器
  • pause(): 暂停计时器
  • resume(): 恢复计时器
  • cancel(): 取消计时器
  • getState(): 获取当前状态
  • getInterval(): 获取当前 tick 间隔
  • setInterval(long newInterval, int mode): 修改 tick 间隔,任意状态下均可调用;返回 boolean 表示是否生效——newInterval 为非正数时不生效并返回 false,与当前间隔相同时为无操作并返回 true;mode 取值见 2.5 IntervalChangeMode

2.1.3 回调方法

millisFly:计时器运行的已飞逝毫秒数(不含暂停时间)

  • onStart(long millisFly): 计时器启动时调用
  • onTick(long millisFly): 每个间隔触发
  • onPause(long millisFly): 计时器暂停时调用
  • onResume(long millisFly): 计时器恢复时调用
  • onCancel(long millisFly): 计时器取消时调用

2.2 CountDownTimer

2.2.1 构造函数

CountDownTimer(long millisDuration, long interval)

CountDownTimer(long millisDuration, long interval, CountDownTimer.Option option)

millisDuration 与 interval 均必须大于 0,否则抛出 IllegalArgumentException。省略 option 时使用默认配置(tickWhenStart = false、tickWhenFinish = false)。

2.2.2 方法

  • start(): 启动倒计时
  • pause(): 暂停倒计时
  • resume(): 恢复倒计时
  • cancel(): 取消倒计时
  • getState(): 获取当前状态
  • getFutureDuration(): 获取倒计时总时长
  • getInterval(): 获取当前 tick 间隔
  • setInterval(long newInterval, int mode): 修改 tick 间隔,任意状态下均可调用;返回 boolean 表示是否生效——newInterval 为非正数时不生效并返回 false,与当前间隔相同时为无操作并返回 true;若在 IMMEDIATE 模式下新的下一次 tick 时机已越过结束时间,将立即走结束流程(先按 tickWhenFinish 决定是否触发一次 onTick(0),再触发 onFinish(0))。mode 取值见 2.5 IntervalChangeMode

2.2.3 回调方法

  • onStart(long millisUntilFinished): 倒计时开始时调用
  • onTick(long millisUntilFinished): 每个间隔触发
  • onPause(long millisUntilFinished): 倒计时暂停时调用
  • onResume(long millisUntilFinished): 倒计时恢复时调用
  • onCancel(long millisUntilFinished): 倒计时取消时调用
  • onFinish(long millisDuration): 倒计时自然结束时调用,参数恒为 0;通过 cancel() 中止的倒计时不会触发此回调

2.3 AndroidTick

单次延迟回调工具,无状态机、无暂停/恢复。

2.3.1 构造函数

AndroidTick(long millisDelay)

millisDelay 必须大于 0,否则抛出 IllegalArgumentException。

2.3.2 方法

  • tick(): 触发一次延迟任务;若已有待执行任务,本次调用被静默忽略
  • tick(boolean forceCancel): forceCancel = true 时先取消待执行任务再重新计时;false 时等价于 tick()
  • cancel(): 取消待执行的回调
  • isRunning(): 是否有待执行任务

2.3.3 回调方法

  • onTick(AndroidTick thisInstance, int count): 延迟到达时调用。thisInstance 为当前实例;count 为累计触发次数,从 1 开始,cancel() 不会将其重置

2.4 配置选项

2.4.1 AndroidTimer.Option

AndroidTimer.Option option = new AndroidTimer.Option(
boolean tickWhenStart  // 启动时是否立即触发一次onTick
);

另有无参构造 new AndroidTimer.Option(),等价于 new AndroidTimer.Option(false)。

2.4.2 CountDownTimer.Option

CountDownTimer.Option option = new CountDownTimer.Option(
boolean tickWhenStart,   // 启动时是否立即触发一次onTick
boolean tickWhenFinish   // 完成时是否触发一次onTick
);

另有无参构造 new CountDownTimer.Option(),等价于 new CountDownTimer.Option(false, false)。Kotlin DSL 的 option 参数默认值即为该无参构造。

2.5 IntervalChangeMode

setInterval(long newInterval, int mode) 的 mode 参数控制新间隔何时生效,两个计时器共用同一枚举:

  • IntervalChangeMode.IMMEDIATE:以上次 tick 为基准按新间隔重算下一次 tick(即 上次 tick + newInterval),再钳到当前时刻(RUNNING 为调用时刻,PAUSED 为暂停时刻)之后;也就是说,调小间隔若新的 tick 时机尚未到达则对齐上次 tick、若已越过当前时刻则立即触发并从触发点重锚,调大间隔同样对齐上次 tick。PAUSED 状态无法触发,因而钳到暂停时刻的逾期 tick 会在 resume() 的瞬间触发(两者在 fly-time 上等价)。
  • IntervalChangeMode.NEXT_TICK:不影响已排定的下一次 tick,新间隔从该 tick 之后开始生效

⚠️ 0.4.3 起 IMMEDIATE 语义变更(破坏性):0.4.2 及更早版本是「以当前时刻为基准」(now + newInterval)重新计算;自 0.4.3 改为上述「以上次 tick 为基准」。若原先依赖旧行为,请留意升级后下一次 tick 时机的差异。

timer.setInterval(500L, IntervalChangeMode.IMMEDIATE);
timer.setInterval(500L, IntervalChangeMode.NEXT_TICK);

3. 状态管理

AndroidTimer 与 CountDownTimer 共用以下状态(AndroidTick 无状态机):

  • IDLE: 初始状态,计时器未启动
  • RUNNING: 运行中状态
  • PAUSED: 暂停状态

状态转换图:

stateDiagram-v2
    [*] --> IDLE
    IDLE --> RUNNING: start()
    RUNNING --> PAUSED: pause()
    PAUSED --> RUNNING: resume()
    PAUSED --> RUNNING: start() 重启
    RUNNING --> IDLE: cancel()
    PAUSED --> IDLE: cancel()
    RUNNING --> IDLE: 自然结束(仅 CountDownTimer)
Loading

3.1 状态行为说明

  • start():仅在 RUNNING 状态下被静默忽略。IDLE 下正常启动;PAUSED 下会完整重启——计时基准归零,已累计的 millisFly(倒计时则为剩余时长)被丢弃,等同于一次全新的 start()。
  • 若只想从 PAUSED 继续,请用 resume(),不要用 start()。
  • 从 RUNNING 重置计时器,需先 cancel() 归位至 IDLE,再 start()。
  • pause() 仅在 RUNNING 下生效,resume() 仅在 PAUSED 下生效,cancel() 在 IDLE 下无效——三者在错误状态下均静默忽略。
  • CountDownTimer 倒计时自然结束时状态自动回到 IDLE 并触发 onFinish,此路径不触发 onCancel。

4. 开发

4.1 环境要求

  • minSdk 21 / compileSdk 36
  • 构建需 JDK 17+(字节码目标 Java 8)
  • Gradle 8.0+(当前 8.13)
  • Kotlin 2.0.21、coroutines 1.9.0(仅 android-timer-kt)

4.2 构建项目

./gradlew build

4.3 运行测试

./gradlew test

5. Kotlin API(android-timer-kt)

提供 DSL 构建函数和 Flow 接口,适用于 Kotlin 项目。Kotlin 类位于 com.github.xesam.android.timer.kt 包,使用时按需导入:

import com.github.xesam.android.timer.kt.androidTimer
import com.github.xesam.android.timer.kt.countDownTimer
import com.github.xesam.android.timer.kt.androidTick
import com.github.xesam.android.timer.kt.TimerState

5.1 AndroidTimer(Kotlin)

// 纯 DSL 用法
val timer = androidTimer(1000L, onTick = { ms -> updateUI(ms) })
timer.start()
timer.pause()
timer.resume()
timer.cancel()

// Flow 用法(观测 tick 和状态)
val timer = androidTimer(1000L)
lifecycleScope.launch {
    timer.tickFlow.collect { ms -> updateProgress(ms) }
}
lifecycleScope.launch {
    timer.stateFlow.collect { state ->
        when (state) {
            TimerState.RUNNING -> showRunning()
            TimerState.PAUSED  -> showPaused()
            TimerState.IDLE    -> showIdle()
        }
    }
}
timer.start()

也可直接读取 timer.state: TimerState 获取当前状态(等价于 stateFlow.value),无需订阅 Flow。

5.2 CountDownTimer(Kotlin)

onFinish 回调与 finishFlow 均可单独使用,任选其一即可;此示例仅展示两者可共存。

// DSL + Flow 混用
val countdown = countDownTimer(
    duration = 10_000L,
    interval = 100L,
    onFinish = { showResult() }
)
lifecycleScope.launch {
    countdown.tickFlow.collect { ms -> updateCountdown(ms) }
}
lifecycleScope.launch {
    countdown.finishFlow.collect { navigateToResult() }
}
countdown.start()

5.3 AndroidTick(Kotlin)

val tick = androidTick(500L, onTick = { count ->
    Log.d("Tick", "Triggered $count times")
})
tick.tick()        // 触发延迟任务
tick.tick(true)    // 取消上次,重新计时
tick.cancel()      // 取消待执行回调

Kt* 类均继承了对应 Java 类的全部方法。例如 KtAndroidTimer/KtCountDownTimer 同样可调用 setInterval(newInterval, mode)(见 2.5 IntervalChangeMode)、getInterval()、getState() 等。

6. 变更记录

6.1 0.4.3

  • setInterval(long newInterval, int mode) 签名由 void 改为返回 boolean:非正数间隔不再抛异常,改为不生效并返回 false;与当前间隔相同时为无操作并返回 true(构造函数仍对非正数间隔抛 IllegalArgumentException)
  • 破坏性变更:IntervalChangeMode.IMMEDIATE 语义由「以当前时刻为基准」改为「以上次 tick 为基准」重算下一次 tick,详见 2.5 IntervalChangeMode

6.2 0.4.2

  • 文档修正:新增 §2.3 AndroidTick 正式 API 章节;补全两个计时器的构造参数校验、Option 无参构造说明
  • 状态图与 §3.1 补充 PAUSED 下 start() 会完整重启、CountDownTimer 自然结束回到 IDLE 两条真实行为;澄清 onFinish 语义(参数恒为 0、cancel() 不触发)
  • android-timer-kt 将 kotlinx-coroutines 依赖由 implementation 改为 api,修复消费者使用 tickFlow/stateFlow/finishFlow 时缺失 Flow 类型的问题

6.3 0.4.1

  • AndroidTimer/CountDownTimer 新增 setInterval(long newInterval, int mode),支持运行时动态修改 tick 间隔,mode 取值 IntervalChangeMode.IMMEDIATE/NEXT_TICK,详见 2.5 IntervalChangeMode

6.4 0.4.0

  • Kotlin 扩展独立为 android-timer-kt 模块,类迁移至 com.github.xesam.android.timer.kt 包
  • Kotlin 侧新增 state: TimerState 只读属性与 TimerState 枚举,替代 Java 继承的 getState()
  • 修复 CountDownTimer 结束路径在 tickWhenFinish=true 时重复触发 onTick(0) 的问题
  • AndroidTick 构造校验延迟 > 0,新增 isRunning() 公开状态查询
  • 回调(onStart/onTick/onPause/onResume/onCancel/onFinish)改为在同步锁外派发,避免用户回调重入引发状态惊奇
  • 接入 detekt/checkstyle 静态检查
  • 依赖升级至 Kotlin 2.0.21、coroutines 1.9.0、Gradle 8.13

7. 许可证

Copyright 2025-2026 xesam

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

8. 联系方式

如有问题或建议,请通过以下方式联系:

  • GitHub Issues: 创建Issue

About

一个轻量级的Android计时器库,提供 AndroidTimer、CountDownTimer、AndroidTick 三个相互独立的核心组件,支持开始/暂停/恢复/停止。

Topics

androidandroid-timertimer

Resources

Readme
Apache-2.0 license
Activity

Stars

30 stars

Watchers

1 watching

Forks

9 forks
Report repository

Releases

Packages

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.