당신은, 그들은 일반적으로 활동 컨텍스트에서 호출 할 수 있습니다 정적 메서드에 TextToSpeech를 정의 할 경우에도 할 수 있습니다 여전히 종료 소위 TextToSpeech를 사용하는 활동이 파괴 될 때마다 TextToSpeech. 문서 상태는 : 그것은 활동의 들의 OnDestroy() 메소드에서이 메소드를 호출하는 예를 들어 좋은 방법이다
그래서 TextToSpeech 엔진은 이 완전히 정지 될 수 있습니다. 각 후 그것을 종료 할 필요는 없습니다 한편
http://developer.android.com/reference/android/speech/tts/TextToSpeech.html#shutdown()
내가 한 활동이 실행되는 초기화 TextToSpeech 객체를 유지하는 것이 좋습니다 그래서 사용합니다. 이렇게하면 각 "말하기"작업 전에 TextToSpeech가 초기화되지 않습니다. 기기의 TextToSpeech가 초기화 된 후에는 일반적으로 매우 무거운 작업이 아니지만 여전히 얻을 수있는 몇 밀리 초입니다.
NTSus 5에서 TTS를 시작하는 데는 처음 약 1.3 초가 걸리고 그 후에 각 인스턴스화에는 50 ~ 80ms가 소요되며 실제로 저장할 수 있습니다.
메모리 누수가 염려되는 경우 일반적으로 Activity 컨텍스트가되는 컨텍스트 대신 context.getApplicationContext()를 사용하여 응용 프로그램 컨텍스트를 사용하여 TTS를 초기화합니다. nKn가 제안 - -
은 또한 GC 그것이 VM이 메모리가 부족 실행해야 재활용 할 수 있도록하기 위해하는 SoftReference를 사용 (이 VM이 OutOfMemoryError를 던졌습니다 전에 모든 SoftReferences 재활용 될 것으로 보장된다, 참조 : http://docs.oracle.com/javase/7/docs/api/java/lang/ref/SoftReference.html)를.
코드를 더욱 향상 시키려면 사용자가 언어를 설치하도록 허용하여 누락 된 언어 사례를 처리해야합니다. 그 전이나 개체가 파괴 된 이후에 수행하지 않은 경우 TextToSpeech 만 인스턴스화 볼 수 있듯이
public class SpeechTxt {
private static SoftReference<TextToSpeech> sTts;
public static void speakOut(final Context context, final String s) {
final Context appContext = context.getApplicationContext();
if (sTts == null) {
sTts = new SoftReference<TextToSpeech>(new TextToSpeech(appContext, new TextToSpeech.OnInitListener(){
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
speak(appContext, s);
}
else {
loadText2SpeechData(appContext);
}
}
}));
}
else {
speak(appContext, s);
}
}
public static void destroyTTS(Context context) {
if (sTts != null && ! sTts.get().isSpeaking()) {
sTts.get().shutdown();
sTts = null;
}
}
private static void speak(Context context, String s) {
if (sTts != null) {
switch (sTts.get().setLanguage(Locale.getDefault())) {
case TextToSpeech.LANG_COUNTRY_AVAILABLE:
case TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE:
case TextToSpeech.LANG_AVAILABLE: {
sTts.get().speak(s, TextToSpeech.QUEUE_ADD, null);
break;
}
case TextToSpeech.LANG_MISSING_DATA: {
loadText2SpeechData(context);
break;
}
case TextToSpeech.LANG_NOT_SUPPORTED: // not much to do here
}
}
}
private static void loadText2SpeechData(Context context) {
try {
Intent installIntent = new Intent(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(installIntent);
}
catch (ActivityNotFoundException ignore) {}
}
}
:
다음은 코드를 향상시킬 수있는 방법을 내 제안입니다. 또한 응용 프로그램 컨텍스트 만 사용하므로 메모리 누수가 없습니다. FLAG_ACTIVITY_NEW_TASK를 사용하고 있기 때문에 응용 프로그램 컨텍스트로 활동을 시작하는 것도 문제가되지 않습니다.
비 활동 컨텍스트 (예 : BroadCastReceiver)에서 TTS를 사용하는 경우에도 TextToSpeech 개체를 초기화하고 소멸 (및 기본 리소스를 해제) 할 수있는 일종의 수명주기가 남아 있습니다. IMO는 SoftReference를 사용할 때 특히 필요하지 않습니다.
브로드 캐스트 리시버 오브젝트가 onReceive 호출 기간 (문맥, 의도)에 대해서만 유효하십시오 브로드 캐스트 리시버는 라이프 사이클을 가지고있는 동안
참고 문서는 것을 말한다있다. 이 함수에서 코드가 반환되면 시스템은 객체가 완료된 것으로 간주하고 더 이상 을 활성화하지 않습니다.
이것은 당신이 onReceive에서 무엇을 할 수 있는지에 중요한 영향 (문맥, 의도) 구현이있다 : 당신이 비동기 작업을 처리하기 위해 함수에서 반환해야하므로, 비동기 작업을 필요로 사용할 수없는 것을, 그러나 에서 BroadcastReceiver는 더 이상 활성 상태가 아니므로 이 완료되기 전에 시스템은 프로세스를 종료 할 수 있습니다.
http://developer.android.com/reference/android/content/BroadcastReceiver.html#ReceiverLifecycle
이것은 말하는 호출이 비동기이기 때문에 당신이 브로드 캐스트 리시버에 TTS를 중지 할 수 있으며이 후 TTS 오브젝트를 파괴에 완료 될 때까지 기다릴 수 없음을 의미합니다. TTS 객체를 파괴하려면 (다시는 필요 없다고 생각하는 경우) 예를 들어 시작해야합니다. 서비스 (또는 UI가없는 활동). 이 서비스는 speak 메서드를 호출하고 OnUtteranceCompletedListener (또는 OnUtteranceProgressListener)가 반환 할 때까지 기다립니다. 그랬 으면 :
그런데 각각의 말을 듣고 나면 TTS 객체를 파괴하려면 실제로 정적 코드를 사용할 필요가 없습니다.
새 인스턴스를 생성하기 전에 종료하고 'null'합니다. –
더 좋은 코드가 있습니까? – HelloCW
onCreate 메소드에서 객체를 초기화하고 onStop에서 객체를 종료하는 방법은 무엇입니까? – nasch