React Native使用react-native-tts包Android端触发NativeEventEmitter警告如何修复
React Native react-native-tts Android端警告修复方案
警告触发原因
new NativeEventEmitter() was called with a non-null argument警告出现的核心原因是Android端react-native-tts原生模块初始化完成前,代码就提前调用了TTS相关API(当前代码在构造函数中直接执行Tts.setDefaultLanguage、调用发音方法时提前注册事件监听器,都触发了这个时机问题),iOS端模块初始化时机更早,因此没有异常。
另外现有代码每次调用voiceTheText都会重复注册事件监听器,会额外导致内存泄漏问题,也需要同步优化。
具体修改步骤
- 移除构造函数中直接调用的
Tts.setDefaultLanguage逻辑,将所有TTS操作挪到Tts.getInitStatus成功回调中执行,确保原生模块初始化完成后再调用相关API - 事件监听器仅全局注册一次,避免重复添加,可根据需求补充监听器移除逻辑
- 所有TTS操作前先等待初始化状态校验完成,避免调用未就绪的原生模块方法
修改后完整代码
import { Platform } from "react-native" import Tts from "react-native-tts" export class VocalizationUtil { constructor() { // 移除构造函数中的TTS API调用,避免提前触发未初始化的原生模块 this.hasInitListener = false } iosConfig = { iosVoiceId: "com.apple.ttsbundle.Moira-compact", //使用的语音ID rate: 0.5, //语速 } androidConfig = { KEY_PARAM_PAN: 0, KEY_PARAM_VOLUME: 0.5, // 0代表静音 KEY_PARAM_STREAM: "STREAM_MUSIC" } // 订阅TTS事件,仅执行一次 createListeners() { if (this.hasInitListener) return Tts.addEventListener("tts-start", event => { }) Tts.addEventListener("tts-finish", event => { }) Tts.addEventListener("tts-cancel", event => { }) this.hasInitListener = true } // 新增销毁方法,页面/实例销毁时调用,避免内存泄漏 destroy() { Tts.removeAllListeners("tts-start") Tts.removeAllListeners("tts-finish") Tts.removeAllListeners("tts-cancel") Tts.destroy() } async voiceTheText(text) { try { // 先校验初始化状态,确保原生模块就绪 await Tts.getInitStatus() // 初始化后再执行配置和操作 if (!this.hasInitListener) { this.createListeners() await Tts.setDefaultLanguage("en-IE") } Tts.stop() //停止发声并清空TTS队列 Tts.speak(`${text}`, Platform.OS === "android" ? this.androidConfig : this.iosConfig) } catch (error) { // 可根据需求处理初始化失败、未安装TTS引擎等异常 } } }
修改后重新打包运行,Android端的警告即可消除,同时也修复了原有代码的监听器重复注册问题。
内容的提问来源于stack exchange,提问作者SoF
相关产品推荐
相关产品推荐

