「鸿蒙 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 开发相关的内容和经验。

相关推荐
SuperHeroWu77 小时前
【HarmonyOS 5】鸿蒙碰一碰分享功能开发指南
华为·harmonyos·应用·分享·碰一碰
lqj_本人8 小时前
鸿蒙OS&UniApp 制作动态加载的瀑布流布局#三方框架 #Uniapp
uni-app·harmonyos
lqj_本人10 小时前
鸿蒙OS&UniApp制作一个小巧的图片浏览器#三方框架 #Uniapp
华为·uni-app·harmonyos
lqj_本人13 小时前
鸿蒙OS&UniApp 开发的下拉刷新与上拉加载列表#三方框架 #Uniapp
华为·uni-app·harmonyos
Lucky me.13 小时前
关于mac配置hdc(鸿蒙)
macos·华为·harmonyos
lqj_本人14 小时前
鸿蒙OS&UniApp 制作个人信息编辑界面与头像上传功能#三方框架 #Uniapp
uni-app·harmonyos
国产化创客15 小时前
OpenHarmony轻量系统--BearPi-Nano开发板网络程序测试
网络·物联网·harmonyos·国产化
天夏已微凉21 小时前
OpenHarmony系统HDF驱动开发介绍(补充)
驱动开发·音视频·harmonyos
特立独行的猫a1 天前
HarmonyOS 【诗韵悠然】AI古诗词赏析APP开发实战从零到一系列(一、开篇,项目介绍)
人工智能·华为·harmonyos·古诗词
幽蓝计划1 天前
鸿蒙跨平台开发教程之Uniapp布局基础
harmonyos