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在接收到回调之后就没有用了。