android TextToSpeech 源码分析

TTS 相关的源码位置:

android / platform / frameworks / base / core / java / android / speech

1.先从TextToSpeech.java分析

构造方法:

public TextToSpeech(Context context, OnInitListener listener) {

        this(context, listener, null);

    }

  public TextToSpeech(Context context, OnInitListener listener, String engine) {

        this(context, listener, engine, null, true);

    }

最终会调用这个构造方法:

 public TextToSpeech(Context context, OnInitListener listener, String engine,

            String packageName, boolean useFallback) {

        mContext = context;

        mInitListener = listener;

        mRequestedEngine = engine;

        mUseFallback = useFallback;

        mEarcons = new HashMap<String, Uri>();

        mUtterances = new HashMap<CharSequence, Uri>();

        mUtteranceProgressListener = null;

        mEnginesHelper = new TtsEngines(mContext);//前面都是赋值操作,主要看这里,new 一个TtsEngines();

        initTts();

    }

我们看一下TtsEngines的构造方法:

public TtsEngines(Context ctx) {

        mContext = ctx;//赋值Context

    }

接下来看initTts()

 private int initTts() {

        // Step 1: Try connecting to the engine that was requested.

        if (mRequestedEngine != null) {//如果我们使用new TextToSpeech(mContext, this)这种方式来构造TTS,则这里的mRequestedEngine肯定等于null

            if (mEnginesHelper.isEngineInstalled(mRequestedEngine)) {

                if (connectToEngine(mRequestedEngine)) {

                    mCurrentEngine = mRequestedEngine;

                    return SUCCESS;

                } else if (!mUseFallback) {

                    mCurrentEngine = null;

                    dispatchOnInit(ERROR);

                    return ERROR;

                }

            } else if (!mUseFallback) {

                Log.i(TAG, “Requested engine not installed: ” + mRequestedEngine);

                mCurrentEngine = null;

                dispatchOnInit(ERROR);

                return ERROR;

            }

        }

        // Step 2: Try connecting to the user’s default engine.

        final String defaultEngine = getDefaultEngine();

        if (defaultEngine != null && !defaultEngine.equals(mRequestedEngine)) {

            if (connectToEngine(defaultEngine)) {

                mCurrentEngine = defaultEngine;

                return SUCCESS;

            }

        }

        // Step 3: Try connecting to the highest ranked engine in the

        // system.

        final String highestRanked = mEnginesHelper.getHighestRankedEngineName();

        if (highestRanked != null && !highestRanked.equals(mRequestedEngine) &&

                !highestRanked.equals(defaultEngine)) {

            if (connectToEngine(highestRanked)) {

                mCurrentEngine = highestRanked;

                return SUCCESS;

            }

        }

        // NOTE: The API currently does not allow the caller to query whether

        // they are actually connected to any engine. This might fail for various

        // reasons like if the user disables all her TTS engines.

        mCurrentEngine = null;

        dispatchOnInit(ERROR);

        return ERROR;

    }

直接看step 2: 

getDefaultEngine();

public String getDefaultEngine() {

        return mEnginesHelper.getDefaultEngine();

    }

调用mEnginesHelper的方法,mEnginesHelper就是之前new 出来的TtsEngines。

TtsEngines的getDefaultEngine()方法:

 /**

     * @return the default TTS engine. If the user has set a default, and the engine

     *         is available on the device, the default is returned. Otherwise,

     *         the highest ranked engine is returned as per {@link EngineInfoComparator}.

     */

    public String getDefaultEngine() {

        String engine = getString(mContext.getContentResolver(),

                Settings.Secure.TTS_DEFAULT_SYNTH);

        return isEngineInstalled(engine) ? engine : getHighestRankedEngineName();

    }

|

|

|

|

|

|

/**

     * @return the package name of the highest ranked system engine, {@code null}

     *         if no TTS engines were present in the system image.

     */

    public String getHighestRankedEngineName() {

        final List<EngineInfo> engines = getEngines();

        if (engines.size() > 0 && engines.get(0).system) {

            return engines.get(0).name;

        }

        return null;

    }

返回系统中最高级别的engine

 /**

     * Information about an installed text-to-speech engine.

     *

     * @see TextToSpeech#getEngines

     */

    public static class EngineInfo {

        /**

         * Engine package name..

         */

        public String name;

        /**

         * Localized label for the engine.

         */

        public String label;

        /**

         * Icon for the engine.

         */

        public int icon;

        /**

         * Whether this engine is a part of the system

         * image.

         *

         * @hide

         */

        public boolean system;

        /**

         * The priority the engine declares for the the intent filter

         * {@code android.intent.action.TTS_SERVICE}

         *

         * @hide

         */

        public int priority;

        @Override

        public String toString() {

            return “EngineInfo{name=” + name + “}”;

        }

    }

setp2中会 把获取到的引擎name赋值给mCurrentEngine, mCurrentEngine = defaultEngine;

然后调用

private boolean connectToEngine(String engine) {

        Connection connection = new Connection();

        Intent intent = new Intent(Engine.INTENT_ACTION_TTS_SERVICE);

        intent.setPackage(engine);

        boolean bound = mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE);

        if (!bound) {

            Log.e(TAG, “Failed to bind to ” + engine);

            return false;

        } else {

            Log.i(TAG, “Sucessfully bound to ” + engine);

            mConnectingServiceConnection = connection;

            return true;

        }

    }

可以看到该方法中去bindService了。

但是这个地方的Connection是个什么东西呢?

就是

initTts方法的最后会调用:

private void dispatchOnInit(int result) {

        synchronized (mStartLock) {

            if (mInitListener != null) {

                mInitListener.onInit(result);

                mInitListener = null;

            }

        }

    }

mInitListener是构造方法中传的参数TextToSpeech(Contex
t context, OnInitListener listener) ,可以看到我们传进去的listener在接收到回调之后就没有用了。

       

    原文作者:Android源码分析
    原文地址: https://blog.csdn.net/qiaoranak/article/details/52709184
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞