目录

Android-百度语音合成工具类封装内存泄漏防护与简化调用

目录

Android 百度语音合成工具类封装:内存泄漏防护与简化调用

适配高版本 Android 系统

使用 Application Context 避免内存泄漏

默认回调支持,调用更简洁

线程安全与资源释放优化

完整代码:BaiduTTSManager.java:

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.NonNull;

import com.baidu.tts.client.SpeechError;
import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.SpeechSynthesizerListener;
import com.baidu.tts.client.TtsMode;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 百度语音合成工具类
 * - 适配高版本 Android 系统
 * - 使用 Application Context 避免内存泄漏
 * - 提供默认回调,简化调用逻辑
 * - 线程安全与资源释放优化
 */
public class BaiduTTSManager {
    private static final String TAG = "BaiduTTSManager";
    private static BaiduTTSManager instance;
    private SpeechSynthesizer speechSynthesizer;
    private Context appContext; // 使用 Application Context
    private Handler mainHandler = new Handler(Looper.getMainLooper());
    private ExecutorService executorService = Executors.newSingleThreadExecutor();
    private TTSState currentState = TTSState.UNINITIALIZED;

    private BaiduTTSManager(Context context) {
        // 使用 Application Context,避免内存泄漏
        this.appContext = context.getApplicationContext();
    }

    /**
     * 获取单例实例
     */
    public static synchronized BaiduTTSManager getInstance(Context context) {
        if (instance == null) {
            instance = new BaiduTTSManager(context);
        }
        return instance;
    }

    /**
     * 初始化 TTS(简化调用,无需回调)
     */
    public void init(String appId, String apiKey, String secretKey) {
        init(appId, apiKey, secretKey, new DefaultTTSInitListener());
    }

    /**
     * 初始化 TTS(带回调)
     */
    public void init(String appId, String apiKey, String secretKey, @NonNull TTSInitListener listener) {
        if (currentState == TTSState.INITIALIZING || currentState == TTSState.INITIALIZED) {
            Log.w(TAG, "TTS is already initializing or initialized");
            return;
        }

        currentState = TTSState.INITIALIZING;
        executorService.execute(() -> {
            try {
                speechSynthesizer = SpeechSynthesizer.getInstance();
                speechSynthesizer.setContext(appContext); // 使用 Application Context
                speechSynthesizer.setAppId(appId);
                speechSynthesizer.setApiKey(apiKey, secretKey);
                speechSynthesizer.initTts(TtsMode.ONLINE);

                currentState = TTSState.INITIALIZED;
                mainHandler.post(() -> listener.onInitSuccess());
            } catch (Exception e) {
                currentState = TTSState.UNINITIALIZED;
                Log.e(TAG, "TTS initialization failed: " + e.getMessage());
                mainHandler.post(() -> listener.onInitFailed(e.getMessage()));
            }
        });
    }

    /**
     * 播报文本(简化调用,无需回调)
     */
    public void speak(String text) {
        speak(text, new DefaultTTSSpeakListener());
    }

    /**
     * 播报文本(带回调)
     */
    public void speak(String text, @NonNull TTSSpeakListener listener) {
        if (currentState != TTSState.INITIALIZED) {
            Log.e(TAG, "TTS is not initialized!");
            mainHandler.post(() -> listener.onSpeakFailed("TTS 未初始化"));
            return;
        }

        if (speechSynthesizer == null) {
            Log.e(TAG, "SpeechSynthesizer is null!");
            mainHandler.post(() -> listener.onSpeakFailed("TTS 初始化失败"));
            return;
        }

        try {
            speechSynthesizer.speak(text);
            setSpeechSynthesizerListener(listener);
            mainHandler.post(() -> listener.onSpeakStart());
        } catch (Exception e) {
            Log.e(TAG, "Speak failed: " + e.getMessage());
            mainHandler.post(() -> listener.onSpeakFailed(e.getMessage()));
        }
    }

    /**
     * 设置 TTS 监听器
     */
    private void setSpeechSynthesizerListener(@NonNull TTSSpeakListener listener) {
        if (speechSynthesizer != null) {
            speechSynthesizer.setSpeechSynthesizerListener(new SpeechSynthesizerListener() {
                @Override
                public void onSynthesizeStart(String s) {
                    // 合成开始
                }

                @Override
                public void onSynthesizeDataArrived(String s, byte[] bytes, int i) {
                    // 合成数据回调
                }

                @Override
                public void onSynthesizeFinish(String s) {
                    // 合成完成
                }

                @Override
                public void onSpeechStart(String s) {
                    // 播报开始
                    mainHandler.post(() -> listener.onSpeakStart());
                }

                @Override
                public void onSpeechProgressChanged(String s, int i) {
                    // 播报进度
                }

                @Override
                public void onSpeechFinish(String s) {
                    // 播报完成
                    mainHandler.post(() -> listener.onSpeakFinish());
                }

                @Override
                public void onError(String s, SpeechError speechError) {
                    // 播报错误
                    mainHandler.post(() -> listener.onSpeakFailed(speechError.description));
                }
            });
        }
    }

    /**
     * 释放资源
     */
    public void release() {
        if (speechSynthesizer != null) {
            speechSynthesizer.release();
            speechSynthesizer = null;
        }
        currentState = TTSState.UNINITIALIZED;
        executorService.shutdown();
    }

    /**
     * TTS 状态枚举
     */
    private enum TTSState {
        UNINITIALIZED, // 未初始化
        INITIALIZING,  // 初始化中
        INITIALIZED,   // 初始化完成
    }

    /**
     * TTS 初始化回调接口
     */
    public interface TTSInitListener {
        void onInitSuccess();
        void onInitFailed(String errorMessage);
    }

    /**
     * TTS 播报回调接口
     */
    public interface TTSSpeakListener {
        void onSpeakStart();
        void onSpeakFinish();
        void onSpeakFailed(String errorMessage);
    }

    /**
     * 默认初始化回调(空实现)
     */
    private static class DefaultTTSInitListener implements TTSInitListener {
        @Override
        public void onInitSuccess() {
            Log.d(TAG, "TTS 初始化成功");
        }

        @Override
        public void onInitFailed(String errorMessage) {
            Log.e(TAG, "TTS 初始化失败: " + errorMessage);
        }
    }

    /**
     * 默认播报回调(空实现)
     */
    private static class DefaultTTSSpeakListener implements TTSSpeakListener {
        @Override
        public void onSpeakStart() {
            Log.d(TAG, "开始播报");
        }

        @Override
        public void onSpeakFinish() {
            Log.d(TAG, "播报完成");
        }

        @Override
        public void onSpeakFailed(String errorMessage) {
            Log.e(TAG, "播报失败: " + errorMessage);
        }
    }
}

使用示例

1. 初始化 TTS

BaiduTTSManager ttsManager = BaiduTTSManager.getInstance(this);
ttsManager.init("你的App ID", "你的API Key", "你的Secret Key");

2. 播报文本

ttsManager.speak("你好,百度语音合成");

3. 带回调的播报

ttsManager.speak("你好,百度语音合成", new BaiduTTSManager.TTSSpeakListener() {
    @Override
    public void onSpeakStart() {
        Log.d(TAG, "开始播报");
    }

    @Override
    public void onSpeakFinish() {
        Log.d(TAG, "播报完成");
    }

    @Override
    public void onSpeakFailed(String errorMessage) {
        Log.e(TAG, "播报失败: " + errorMessage);
    }
});

4. 释放资源

@Override
protected void onDestroy() {
    super.onDestroy();
    if (ttsManager != null) {
        ttsManager.release();
    }
}

5.在 Application 中带回调使用

import android.app.Application;
import android.util.Log;

public class MyApplication extends Application {
    private static final String TAG = "MyApplication";
    private BaiduTTSManager ttsManager;

    @Override
    public void onCreate() {
        super.onCreate();

        // 初始化 TTS
        ttsManager = BaiduTTSManager.getInstance(this);
        ttsManager.init("你的App ID", "你的API Key", "你的Secret Key", new BaiduTTSManager.TTSInitListener() {
            @Override
            public void onInitSuccess() {
                Log.d(TAG, "TTS 初始化成功");
            }

            @Override
            public void onInitFailed(String errorMessage) {
                Log.e(TAG, "TTS 初始化失败: " + errorMessage);
            }
        });

        // 播报文本
        ttsManager.speak("欢迎使用百度语音合成", new BaiduTTSManager.TTSSpeakListener() {
            @Override
            public void onSpeakStart() {
                Log.d(TAG, "开始播报");
            }

            @Override
            public void onSpeakFinish() {
                Log.d(TAG, "播报完成");
            }

            @Override
            public void onSpeakFailed(String errorMessage) {
                Log.e(TAG, "播报失败: " + errorMessage);
            }
        });
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        // 释放资源
        if (ttsManager != null) {
            ttsManager.release();
        }
    }
}

5.在 Application 中不带回调使用

public class MyApplication extends Application {
    private BaiduTTSManager ttsManager;

    @Override
    public void onCreate() {
        super.onCreate();
        ttsManager = BaiduTTSManager.getInstance(this);
        ttsManager.init("你的App ID", "你的API Key", "你的Secret Key");
    }

    public BaiduTTSManager getTTSManager() {
        return ttsManager;
    }
}

优点

高兼容性:

适配 Android 6.0 及以上版本,动态权限处理和存储适配。

内存泄漏防护:

使用 Application Context,避免持有 Activity 引用。

简化调用:

提供默认回调实现,调用方无需强制实现回调接口。

线程安全:

使用线程池管理异步任务,确保线程安全。

资源释放:

在 release 方法中清理所有资源,避免内存泄漏。

总结

该工具类封装了百度语音合成的核心功能,适用于 Android 平台,具有高兼容性、内存泄漏防护和简化调用等优点。通过清晰的接口设计和优化,开发者可以轻松集成语音播报功能,同时避免常见的内存泄漏问题。