Tistory View

Android Develop/tts

tts를 static함수로 만드는 데 실패했다.

God Dangchy What should I do? 2017. 10. 7. 17:13

TextToSpeech를 이용하여 프로그래밍을 하고 있었다.

TextToSpeech의 클래스를 랩핑하기 위한 작업을 위해 트래이닝에 들어갔다.

전체를 Context로 묶고 시작하던 중에 난관에 부딛히고 말았다.


필자가 하고 싶었던 일은

다름과 같은 static함수를 만들어 바로 소리로 출력하고 싶었다.(파일로 저장도 동일한 방법을 써야 한다.)


public static function speak( Context context, String text, String utteranceId, [My Progress Callback]);

이 함수는 자체적으로 TTS엔진을 초기화하고 소리로 출력을 하고 TTS엔진을 소멸하는 과정까지 한번에 처리하는 것이었다.


문제는 TextToSpeech instance를 생성하는 과정에서 OnInitListener를 사용할 때 문제가 발생했다.

이 OnInitListener는 TextToSpeech instance를 생성할 때, ctor의 파라미터로 들어가게 된다.

이 말은 instance가 생성된 이후에나 변수에 할당이 가능하다는 뜻이 된다.

대체 뭔소린지 다음의 코드를 보자.(예제는 실행 불가능 하니.. 그냥 눈으로 확인하라..)


public class 대충클래스이름 implements TextToSpeech.OnInitListener {

private boolean      mInitialized;

private TextToSpeech mTts;

private String       mText;

private String       mUtteranceId;

public static function speak( Context context, String text, String utteranceId, [My Progress Callback] )

{

mInitialized = false;

mText        = text;

....

mTts = new TextToSpeech( context, this ); //***1***

}

@Override

public void onInit(int status)

{

if( status != TextToSpeech.SUCCESS ) {

// 초기화기 실패했음을 사용자가 지정한 콜백에 전달한다.

return;

}

 

 mTts.speak( mText, qumode, NULL, mUtteranceId );  //***2***

}

};


대충 위와 같은 코드로 처리하려고 했다.

이 코드를 실행해보면, 잘 동작하는 것을 알 수 있다.(물론 실행 불가능한 코드다..)


그럼, 이 코드에 문제가 없을 까...?


문제는 ***1***과 ***2***에서 발생한다. 

만약 초기화되는 코드(onInit)가 mTts에 할당되기 전에 실행된다면, ***2***에서 mts는 null을 가지고 있게 된다. 즉 mTts.speak는 수행 될 수 가 없다.

(

수정

위 코드를 여러 디바이스에서 테스트를 해볼 결과 onInit은 MainThread에서 수행되었다. 

즉.. onInit이 실행 될 경우, mTts는 이미 객체가 할 당 된 후다..

그래도 constructor에서 처리되는 건 맘에 안든다..

)


 물론 이렇게 실행될 확률은 정말 작아서 위 코드를 사용해도 되지만, 프로그램에 문제를 안고 사용하는 것은 좀 많이 그렇다.

 

 ***2*** 코드 다음에 일부러 Delay코드는 넣으면 보다 안정성이 향상이 될 테지만, 이 또한 도긴개긴일 뿐...

 

 문제의 가장 큰 오류점은 onInit함수가 호출될 때, TextToSpeech instance를 잡을 방법이 없다는 것이다.

(수정 : 영 방법이 없는 것은 아니지만, global 변수식으로 처리하면 되긴 한다.)

 이는 구글에서 제공하는 onInit함수에 파라미터로 TextToSpeech instance를 넘겨 주었어야 하는 문제다..

 

 

 

 

 

 다음과 같은 다른 시도도 해 보았지만, 필자는 그리 맘에 들지 않았다.

 - TextToSpeech 를 상속받아 this를 낚아채기..(이 거 왜 안되는지.. Java프로그래밍을 필자가 잘 모르는 것일 수도..)

 

 

 

 결국... 어쩔 수 없이... TextToSpeech instance를 미리 만들어 놓는 이 객체를 계속 사용하는 식으로 프로그래밍을 해야 했다.

 

 

 필자의 경우, 마치 global방식으로 초기화하는 프로그램을 만들어야만 했다.

 (필자는 이런 방식의 프로그램을 별로 좋아하지 않는다.)

 


 

 과연 이 문제점을 구글이 해결해 줄지는 의문이다...

 

일단은 global방식으로 사용하지만.. 이 부분은 TTS를 사용하려 하는 다른 App에서 문제가 발생할 수 있다.


따라서, Ref-counting방식으로 변경하려고 한다.



 

 

 



'Android Develop > tts' 카테고리의 다른 글

tts를 static함수로 만드는 데 실패했다.  (0) 2017.10.07
tts 사용  (0) 2017.10.06
Replies
Reply Write