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

bloc从3.x升级至8.0.1出现弃用报错的代码适配方案咨询

Bloc 8.0.1 适配改造方案

Bloc 8.x 版本已完全移除旧版mapEventToStateAPI,所有事件处理逻辑需要迁移到构造函数的on<Event>注册回调中,同时需要补全状态/事件的相等判断逻辑、管理异步订阅资源,具体改造步骤如下:


1. 改造 player_event.dart

原代码中PlayEvent的props为空,会导致Bloc无法区分携带不同电台参数的播放事件,需要将参数加入props列表:

part of 'player_bloc.dart';

@immutable
abstract class PlayerEvent extends Equatable {
  const PlayerEvent();

  @override
  List<Object> get props => [];
}

class PlayEvent extends PlayerEvent {
  final Station station;
  PlayEvent(this.station);

  @override
  List<Object> get props => [station]; // 补全属性,保证事件相等判断正常
}

class PauseEvent extends PlayerEvent {}

2. 改造 player_state.dart

原代码中PlayingState、PausedState的props为空,会导致同类型不同参数的状态被判定为相等,出现UI不更新的问题,需要补全props:

part of 'player_bloc.dart';

@immutable
abstract class PlayerState extends Equatable {
  const PlayerState();

  @override
  List<Object> get props => [];
}

class StoppedState extends PlayerState {}

class PlayingState extends PlayerState {
  final Station currentStation;

  PlayingState(this.currentStation);

  @override
  List<Object> get props => [currentStation]; // 补全属性
}

class PausedState extends PlayerState {
  final Station currentStation;

  PausedState(this.currentStation);

  @override
  List<Object> get props => [currentStation]; // 补全属性
}

3. 重构 player_bloc.dart

需要删除废弃的mapEventToState重写方法,迁移逻辑到on回调,同时管理流订阅避免内存泄漏,修正异步执行顺序:

import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
import 'package:online_radio/radio/radio_player.dart';
import 'package:online_radio/radio/radio_state.dart';
import 'package:online_radio/station.dart';

part 'player_event.dart';
part 'player_state.dart';

class PlayerBloc extends Bloc<PlayerEvent, PlayerState> {
  final RadioPlayer radioPlayer;
  // 存储电台状态流订阅,Bloc销毁时需要取消
  late final StreamSubscription _radioStateSubscription;

  PlayerBloc({@required this.radioPlayer})
      : assert(radioPlayer != null),
        super(StoppedState()) {
    // 注册播放事件处理逻辑
    on<PlayEvent>((event, emit) async {
      final currentState = state;
      if (currentState is StoppedState) {
        await _playNewRadioStation(event);
        emit(PlayingState(event.station));
      } else if (currentState is PausedState) {
        if (currentState.currentStation != event.station) {
          await _playNewRadioStation(event);
        } else {
          _playExistingRadioStation();
        }
        emit(PlayingState(event.station));
      } else if (currentState is PlayingState) {
        if (currentState.currentStation != event.station) {
          await _playNewRadioStation(event);
        } else {
          _playExistingRadioStation();
        }
        emit(PlayingState(event.station));
      }
    });

    // 注册暂停事件处理逻辑
    on<PauseEvent>((event, emit) {
      final currentState = state;
      if (currentState is PlayingState) {
        radioPlayer.pause();
        emit(PausedState(currentState.currentStation));
      }
    });

    // 初始化电台原生状态监听
    _radioStateSubscription = radioPlayer.radioStateStream.listen((radioState) {
      if (radioState == RadioState.PLAYING && state is PausedState) {
        add(PlayEvent((state as PausedState).currentStation));
      }
    });
  }

  // 重写close方法,释放订阅资源
  @override
  Future<void> close() {
    _radioStateSubscription.cancel();
    return super.close();
  }

  void _playExistingRadioStation() {
    radioPlayer.play();
  }

  // 改为async/await写法,保证音频地址设置完成后再触发播放
  Future<void> _playNewRadioStation(PlayEvent playEvent) async {
    await radioPlayer.setUrl(playEvent.station.radioUrl);
    radioPlayer.play();
  }
}

核心改动说明

  • 完全移除Bloc 8.x已删除的mapEventToState方法,所有事件处理统一使用on<Event>注册,使用回调提供的emit方法派发状态,替代旧版yield语法
  • 补全所有Event、State子类的props列表,避免Equatable相等判断失效导致的事件不响应、UI不刷新问题
  • 对原生播放器的状态流订阅做生命周期绑定,Bloc关闭时自动取消订阅,避免内存泄漏和空回调异常
  • 修正切歌逻辑的异步顺序,等待音频地址设置完成后再派发播放状态,避免播放异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:33:10