TextToSpeech.setEngineByPackageName () запускает исключение NullPointerException - PullRequest
2 голосов
/ 29 февраля 2012

Моя активность onInit() содержит вызов TextToSpeech.setEngineByPackageName():

  tts = new TextToSpeech(this, this);
  tts.setEngineByPackageName("com.ivona.tts.voicebeta.eng.usa.kendra");

Он работает на устройстве Android 2.2.2, но на устройстве Android 2.3.4 он генерирует исключение NullPointerException со следующей трассировкой стека:

 E/TextToSpeech.java - setEngineByPackageName(3423): NullPointerException
 W/System.err(3423): java.lang.NullPointerException
 W/System.err(3423):    at android.os.Parcel.readException(Parcel.java:1328)
 W/System.err(3423):    at android.os.Parcel.readException(Parcel.java:1276)
 W/System.err(3423):    at android.speech.tts.ITts$Stub$Proxy.setEngineByPackageName(ITts.java:654)
 W/System.err(3423):    at android.speech.tts.TextToSpeech.setEngineByPackageName(TextToSpeech.java:1356)

Поскольку я предоставляю жестко запрограммированный строковый параметр, я знаю, что этот параметр не является причиной того, что вызывает исключение NullPointerException.

Я также знаю, что setEngineByPackageName () устарела, но это только после API 14, так что это не может быть причиной.

Есть идеи, что может вызвать это исключение NullPointerException?

РЕДАКТИРОВАТЬ : Меня не волновало бы «почему», если бы это не привело к бесконечной бомбардировке:

I/TextToSpeech.java(3652): initTts() successfully bound to service

Далее следуют звонки на onInit() (системой, а не моим кодом).

Я надеюсь, что если я пойму, почему это происходит, я могу остановить бомбардировку onInit() с и изящно восстановиться после ошибки.

Ответы [ 2 ]

4 голосов
/ 29 февраля 2012

Установлен ли двигатель TTS, на который вы ссылаетесь, на устройстве 2.3.4?Если это так, это может быть ошибка платформы.

РЕДАКТИРОВАТЬ: Не помню, какие результаты я получил, когда я сделал это, но вызов setEngineByPackageName(), когда пакет не существует, не очень хорошая идея.Проверьте, установлен ли он, и не пытайтесь использовать его, если это не так.Что-то вроде:

boolean isPackageInstalled(String packageName) {
  PackageManager pm = context.getPackageManager();
  try {
    PackageInfo pi = pm.getPackageInfo(packageName, 0);

    return pi != null;
  } catch (NameNotFoundException e) {
    return false;
  }
}
1 голос
/ 29 февраля 2012

Попытка исследовать это самостоятельно, если эксперта по этому вопросу нет рядом:

Трассировка стека NullPointerException печатается самой setEngineByPackageName() в обработчике перехвата для этого предложения try:

try {
    result = mITts.setEngineByPackageName(enginePackageName);
    if (result == TextToSpeech.SUCCESS){
        mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = enginePackageName;
    }
} 

Что говорит о том, что любое из следующего является нулевым:

  1. 1010 * митенки *
  2. mCachedParams

mCachedParams вряд ли будет нулевым, поскольку он инициализируется в конструкторе. Так что это оставляет нас с mITts:

Если я изучу TextToSpeech.initTts(), я легко обнаружу 2 точки, в которых значения MITT могут оставаться нулевыми:

  1. onServiceDisconnected ()

Но почему это происходит только на устройстве 2.3.4? Это все еще загадка.

Возможная подсказка: метод TextToSpeech.initTts() заканчивается следующим комментарием:

mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
// TODO handle case where the binding works (should always work) but
//      the plugin fails

Что может объяснить, почему я получаю заграждение onInit() s ("initTts () успешно привязан к сервису"): привязка всегда работает, но, поскольку пакет не установлен, "плагин не работает".

Вопрос теперь в том, как остановить этот бесконечный цикл ...

...