You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter实现华为推送时如何让Future等待回调触发后返回token

实现方案

Dart 内置的 Completer 类可以完美实现将回调式异步逻辑封装为 Future,具体实现代码如下:

import 'dart:async';
import 'package:flutter/services.dart';
import 'package:huawei_push/huawei_push.dart';

class PushNotificationsService {
  // 可选:缓存已获取的token,避免重复请求
  String? _cachedToken;
  // 用于控制Future完成状态的核心实例
  Completer<String?>? _tokenCompleter;
  // 流订阅对象,用于后续取消监听避免内存泄漏
  StreamSubscription? _tokenStreamSubscription;

  Future<String?> getPushNotificationsToken() async {
    // 已有缓存token直接返回,可根据业务需求调整是否添加过期逻辑
    if (_cachedToken != null) return _cachedToken;
    // 已有正在进行的token请求,直接返回对应Future避免重复请求
    if (_tokenCompleter != null) return _tokenCompleter!.future;

    _tokenCompleter = Completer<String?>();

    // 注册token事件监听
    _tokenStreamSubscription = Push.getTokenStream.listen(
      (event) {
        _cachedToken = event as String;
        // 确认Completer未完成再执行操作,避免重复完成抛出异常
        if (!_tokenCompleter!.isCompleted) {
          _tokenCompleter!.complete(_cachedToken);
        }
        _clearTempResources();
      },
      onError: (error) {
        if (!_tokenCompleter!.isCompleted) {
          if (error is PlatformException) {
            // 可根据业务需要选择返回null或者抛出错误
            // 抛出错误写法:_tokenCompleter!.completeError(error.message ?? "获取推送token失败");
            _tokenCompleter!.complete(null);
          } else {
            _tokenCompleter!.complete(null);
          }
        }
        _clearTempResources();
      },
    );

    // 必须主动调用getToken才会触发流回调,不要遗漏此步骤
    try {
      await Push.getToken("");
    } catch (e) {
      if (!_tokenCompleter!.isCompleted) {
        _tokenCompleter!.complete(null);
      }
      _clearTempResources();
    }

    return _tokenCompleter!.future;
  }

  // 清理临时资源避免内存泄漏
  void _clearTempResources() {
    _tokenStreamSubscription?.cancel();
    _tokenStreamSubscription = null;
    _tokenCompleter = null;
  }

  // 可选:提供清空缓存token的方法,适配用户退出登录等业务场景
  void clearTokenCache() {
    _cachedToken = null;
  }
}

注意事项

  • 上述实现完全适配你要求的调用方式,业务层可直接通过 String? token = await PushNotificationsService().getPushNotificationsToken(); 调用
  • 如果选择抛出错误的实现方式,业务层调用时需要配合 try-catch 捕获异常做对应处理
  • 可根据业务需求调整是否保留token缓存逻辑,不需要直接删除对应代码即可

内容的提问来源于stack exchange,提问作者AndreiBogdan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 21:48:01