TextToSpeechをgoogleのサンプル通りに実装するとleakCanaryが頻繁にleakを検出するので、
色々試して、やっとleakが検出されなくなったのでメモ
方法
- onDestroy()でshutdown()
- ContextはActivityではなくApplicationContextを渡す。
- SoftReferenceを使用する。
onDestroy()でshutdown()
これは普通にgoogleのサンプルでもやっている。
当然やらないとTextToSpeechがContextを保持したままなのでメモリリークする。
@Override
protected void onDestroy() {
if (textToSpeech != null) {
textToSpeech.get().setOnUtteranceProgressListener(null);
textToSpeech.get().shutdown();
}
textToSpeech = null;
}
しかし、これだけではOutOfMemoryはほぼ起こらないですが、leakは度々検出されます。
ContextはActivityではなくApplicationContextを渡す。
textToSpeechManager = new TextToSpeechManager(getApplicationContext(), this);
これでほぼOutOfMemoryで落ちることはないのですが、それでもまだleakは検出されます。
SoftReferenceを使用する。
private SoftReference<TextToSpeech> textToSpeech;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textToSpeech = new SoftReference<TextToSpeech>(new TextToSpeech(getApplicationContext(), this));
}
private void init(Context context) {
}
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
if (textToSpeech.get().isLanguageAvailable(locale) >= TextToSpeech.LANG_AVAILABLE) {
textToSpeech.get().setLanguage(locale);
} else {
Log.e("TTS", "Not support locale.");
}
}
}
こんな感じで実装するとleakが検出されなくなりました。
参考
最終的に行き着いた答えがstack overflowにありました。
How to release the static var of TextToSpeech in order to avoid leak?