Flutter通过Event Channel从Kotlin获取Spotify SDK数据流遇mEventSink为空问题
解决Flutter Event Channel无法接收Spotify SDK数据流的问题
你遇到的核心问题是MethodChannel和EventChannel使用了完全独立的插件实例,导致你在initEventStream方法里操作的mEventSink,和onListen中初始化的mEventSink根本不是同一个对象——这就是为什么日志会打印mEventSink == null。
问题根源拆解
看你registerWith方法里的代码:
channel.setMethodCallHandler(Spotifysdk04Plugin(registrar)) // ... eventChannel.setStreamHandler(Spotifysdk04Plugin(registrar))
这里每次调用Spotifysdk04Plugin(registrar)都会生成一个全新的插件对象,处理方法调用的实例和处理事件流的实例完全分离。当Flutter端发起监听触发onListen时,是第二个实例的mEventSink被赋值,但你在initEventStream里访问的是第一个实例的mEventSink,自然一直是null。
修复方案:共用同一个插件实例
只创建一次插件对象,同时给MethodChannel和EventChannel使用:
companion object { @JvmStatic fun registerWith(registrar: Registrar) { // 创建唯一的插件实例 val pluginInstance = Spotifysdk04Plugin(registrar) val channel = MethodChannel(registrar.messenger(), "spotifysdk") channel.setMethodCallHandler(pluginInstance) val eventChannel = EventChannel(registrar.messenger(), "timerStream") eventChannel.setStreamHandler(pluginInstance) } }
额外优化建议
- 确保Flutter端先启动监听再调用
initEventStream:只有当Flutter端通过receiveBroadcastStream()发起监听,原生端的onListen才会被调用,mEventSink才会被赋值。Flutter端代码示例:final EventChannel _timerChannel = EventChannel('timerStream'); StreamSubscription? _timerSubscription; @override void initState() { super.initState(); // 先启动监听 _timerSubscription = _timerChannel.receiveBroadcastStream().listen((position) { print('收到播放进度:$position'); }); // 再调用初始化数据流的方法 _channel.invokeMethod('initEventStream'); } @override void dispose() { _timerSubscription?.cancel(); super.dispose(); } - 可以考虑把订阅PlayerState的逻辑移到
onListen中:这样能确保只有当mEventSink存在时才开始发送事件,避免空指针风险,比如:override fun onListen(arguments: Any?, eventSink: EventChannel.EventSink) { mEventSink = eventSink // 在这里启动PlayerState订阅 spotifyAppRemote?.playerApi?.subscribeToPlayerState() ?.setEventCallback { playerState -> val position = playerState.playbackPosition.toDouble() mEventSink?.success(position) } }
内容的提问来源于stack exchange,提问作者Jonas Frei
相关产品推荐
相关产品推荐

