collectOnLifecycle<T> method

Stream<T> collectOnLifecycle<T>({
  1. LifecycleState targetState = LifecycleState.started,
  2. bool runWithDelayed = false,
  3. bool collectBlockError = false,
  4. bool ignoreBlockError = false,
  5. Cancellable? cancellable,
  6. required FutureOr<T> block(
    1. Cancellable cancellable
    ),
})

当高于某个状态时执行给定的block,并将结果收集起来为Stream

  • collectBlockError 当发生错误时将错误也收集起来,值为 false 时ignoreBlockError有效
  • ignoreBlockError是否忽略错误 值为 false 时直接报错

Implementation

Stream<T> collectOnLifecycle<T>(
    {LifecycleState targetState = LifecycleState.started,
    bool runWithDelayed = false,
    bool collectBlockError = false,
    bool ignoreBlockError = false,
    Cancellable? cancellable,
    required FutureOr<T> Function(Cancellable cancellable) block}) {
  if (cancellable?.isUnavailable == true) return Stream<T>.empty();

  StreamController<T> controller = StreamController();
  controller.bindCancellable(makeLiveCancellable(other: cancellable));

  Cancellable? checkable;
  final observer = LifecycleObserver.stateChange((state) async {
    if (state >= targetState &&
        (checkable == null || checkable?.isUnavailable == true)) {
      checkable = makeLiveCancellable(other: cancellable);
      try {
        if (runWithDelayed) {
          //转到下一个事件循环,可以过滤掉连续的状态变化
          await Future.delayed(Duration.zero);
        }
        if (checkable!.isUnavailable) return;
        final result = block(checkable!);
        if (result is Future<T>) {
          await Future.delayed(Duration.zero);
          if (checkable?.isAvailable == true) {
            final r = await result;
            if (checkable?.isAvailable == true) controller.add(r);
          }
        } else {
          controller.add(result);
        }
      } catch (exception, stack) {
        if (collectBlockError) {
          controller.addError(exception, stack);
        } else if (!ignoreBlockError) {
          FlutterError.reportError(FlutterErrorDetails(
            exception: exception,
            stack: stack,
            library: 'an_lifecycle_cancellable',
            context: ErrorDescription('collectOnLifecycle run block error'),
          ));
        }
      }
    } else if (state < targetState && checkable?.isAvailable == true) {
      checkable?.cancel();
      checkable = null;
    }
  });

  addLifecycleObserver(observer, fullCycle: true);

  controller.onCancel =
      () => removeLifecycleObserver(observer, fullCycle: false);

  cancellable?.onCancel
      .then((value) => removeLifecycleObserver(observer, fullCycle: false));

  return controller.stream;
}