LoginSignup
5
8

More than 5 years have passed since last update.

[android] TextToSpeechのleak対策

Last updated at Posted at 2017-04-18

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?

5
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
8