「鸿蒙 NEXT」基于 taskpool 实现自定义 Timer 工具类

前言

之前在使用原生的 Timer 定时器实现定时任务时,发现当切换页面或应用切换至后台时,Timer 也会被冻结。如何实现可全局调用,支持后台执行的定时任务呢?我想到了使用 taskpool 任务池实现定时任务,在熟练使用 taskpool 实现定时任务后,进一步将其封装为一个自定义 Timer 工具类方便复用。

实现技术

  • 基于 API 12 ,理论上 13 和 14 版本也可以正常使用;
  • taskpool 多线程任务池,原生 Timer 的替代方案,该 API 下有 executeDelayed() 和 executePeriodically() 方法分别可以实现延时任务和周期任务;
  • emitter 事件订阅,类似安卓开发的 eventbus。由于 taskpool 构造时传入的函数,仅允许序列化支持类型作为入参,于是借助 emitter 做一层中转,通知到自定义 Timer 类触发相应的回调。

实现代码

新建文件 FuTimer.ets,所有实现代码写在同一文件下就好。

  1. 设计定时器的回调接口,在接收到 onTask() 回调时,调用需要定时/周期性执行的任务方法:
typescript 复制代码
export interface TimerCallback {
  onStart: () => void;  // 定时器开始
  onCancel: () => void; // 定时器取消
  onTask: () => void;   // 定时任务触发时的回调
}
  1. 自定义工具类 Timer 实现:
kotlin 复制代码
import { taskpool } from "@kit.ArkTS"
import { BusinessError, emitter, systemDateTime } from "@kit.BasicServicesKit";

export class Timer {
  public constructor(callback: TimerCallback) {
    this.timerName =  `futimer_${systemDateTime.getTime()}`;
    this.timerCallback = callback;

    emitter.on(this.timerName, () => {
      if (this.timerCallback) {
        this.timerCallback.onTask();
      }
    });
  }

  private timerName: string;  // 自定义 Timer 唯一名称,与 emitter 订阅事件绑定
  private timerTask: taskpool.Task | undefined;
  private timerCallback: TimerCallback | undefined;

  /*
   * isRepeat: 是否重复执行任务,false 只执行一次, true 会周期性地执行
   * interval:任务执行间隔时间
   */
  public start(isRepeat: boolean, interval: number) {
    // 取消该定时器上一个任务
    if (this.timerTask) {
      this.cancel();
    }
    
    // 开始执行当前任务
    if (this.timerCallback) {
      this.timerCallback.onStart();
    } else {
      return;
    }
    
    // 重置定时任务
    this.timerTask = new taskpool.Task(executeTask, this.timerName);
    if (isRepeat) {
      taskpool.executePeriodically(interval, this.timerTask);
    } else {
      taskpool.executeDelayed(interval, this.timerTask);
    }
  }

  public cancel() {
    try {
      if (this.timerTask) {
        taskpool.cancel(this.timerTask);
      }
    } catch (e) {
      let error = e as BusinessError;
    } finally {
      this.timerTask = undefined;
      if (this.timerCallback) {
        this.timerCallback.onCancel();
      }
    }
  }

  // 销毁定时器,此时再调用 start() 方法无效
  public destroy() {
    this.cancel();
    emitter.off(this.timerName);
    this.timerTask = undefined;
    this.timerCallback = undefined;
  }
}

export interface TimerCallback {
  onStart: () => void;
  onCancel: () => void;
  onTask: () => void;
}

@Concurrent
function executeTask(timerName: string) {
  emitter.emit(timerName);
}

ps:工具类我写在模块下,需要在模块的 Index.ets 中将其 export 出来:

javascript 复制代码
export * as futimer from './src/main/ets/utils/FuTimer'

调用示例

现在使用封装好的定时器工具,实现一个简单的计时功能:

typescript 复制代码
import { futimer } from 'fusdk'; // fusdk 是我定义的本地模块依赖名称,这个不重要了

@Entry
@Component
struct Index {
  @State count: number = 0;

  @State timer: futimer.Timer = new futimer.Timer({
    onStart: () => {
      console.debug('定时器启动');
    },
    onCancel: () => {
      console.debug('定时器取消');
    },
    onTask: () => {
      this.count++;
      console.debug(`第 ${this.count} 次执行任务`);
    }
  });

  build() {
    Column() {
      Text(`现在是第 ${this.count} 秒`)

      Button('开始计时')
        .onClick(() => {
          this.timer.start(true, 1000);
        })

      Button('暂停计时')
        .onClick(() => {
          this.timer.cancel();
        })
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.SpaceEvenly)
  }
}

效果图:

结语

笔者也是正在学习鸿蒙 NEXT 开发的小菜鸟一枚,希望分享的内容能对你有帮助,也欢迎给予建议,今后也会争取在这里分享更多鸿蒙 NEXT 开发相关的内容和经验。

相关推荐
幽蓝计划9 小时前
HarmonyOS NEXT仓颉开发语言实战案例:动态广场
华为·harmonyos
万少15 小时前
第五款 HarmonyOS 上架作品 奇趣故事匣 来了
前端·harmonyos·客户端
幽蓝计划16 小时前
HarmonyOS NEXT仓颉开发语言实战案例:电影App
华为·harmonyos
HMS Core18 小时前
HarmonyOS免密认证方案 助力应用登录安全升级
安全·华为·harmonyos
生如夏花℡18 小时前
HarmonyOS学习记录3
学习·ubuntu·harmonyos
伍哥的传说18 小时前
鸿蒙系统(HarmonyOS)应用开发之手势锁屏密码锁(PatternLock)
前端·华为·前端框架·harmonyos·鸿蒙
遇到困难睡大觉哈哈1 天前
HarmonyOS 公共事件机制介绍以及多进程之间的通信实现(9000字详解)
华为·harmonyos
幽蓝计划1 天前
HarmonyOS NEXT仓颉开发语言实战案例:外卖App
开发语言·harmonyos
伍哥的传说1 天前
鸿蒙系统(HarmonyOS)应用开发之实现电子签名效果
开发语言·前端·华为·harmonyos·鸿蒙·鸿蒙系统
Georgewu2 天前
【HarmonyOS】应用开发拖拽功能详解
harmonyos