解决使用LeakCanary检测到的TTS内存泄漏

问题描述 投票:0回答:1

这是LeakCanary检测到的内存泄漏的描述:(当按下Android后退按钮时发生)

1 APPLICATION LEAKS

    References underlined with "~~~" are likely causes.
    Learn more at https://squ.re/leaks.

    356182 bytes retained by leaking objects
    Displaying only 1 leak trace out of 2 with the same signature
    Signature: 2276fec44ae233e0d5bb5b82648d5836c07e3b33
    ┬───
    │ GC Root: Global variable in native code
    │
    ├─ android.speech.tts.TextToSpeech$Connection$1 instance
    │    Leaking: UNKNOWN
    │    Anonymous subclass of android.speech.tts.ITextToSpeechCallback$Stub
    │    ↓ TextToSpeech$Connection$1.this$1
    │                                ~~~~~~
    ├─ android.speech.tts.TextToSpeech$Connection instance
    │    Leaking: UNKNOWN
    │    ↓ TextToSpeech$Connection.this$0
    │                              ~~~~~~
    ├─ android.speech.tts.TextToSpeech instance
    │    Leaking: UNKNOWN
    │    ↓ TextToSpeech.mContext
    │                   ~~~~~~~~
    ╰→ com.example.price.SignUpDisplay instance
    ​     Leaking: YES (ObjectWatcher was watching this because com.example.price.SignUpDisplay received Activity#onDestroy() callback and Activity#mDestroyed is true)
    ​     key = 6965e004-28de-464b-87d7-2668461623e7
    ​     watchDurationMillis = 30282
    ​     retainedDurationMillis = 25282

这是在我的活动中初始化tts的方式:

protected fun initializeTextToSpeech() {
        mtts = TextToSpeech(this, TextToSpeech.OnInitListener { status ->
            // If a success, set the language
            if (status == TextToSpeech.SUCCESS) {
                res = mtts.setLanguage(Locale.UK)
            } else {
                Toast.makeText(
                    this,
                    "Feature not supported in your device", Toast.LENGTH_SHORT
                ).show()
            }
        })
    }

这是onDestroy方法:

override fun onDestroy() {
        if (mtts != null) {
            mtts.stop()
            mtts.shutdown()
        }
        super.onDestroy()
    }

为什么会有泄漏,该如何解决?

我也在日志中收到此警告-我不确定它有多严重,或者是否与泄漏有关:

W/TextToSpeech: stop failed: not bound to TTS engine
android-studio memory-leaks text-to-speech back-button leakcanary
1个回答
0
投票

问题是TextToSpeech对其构造函数中提供的上下文保持强引用,Connection实例对TextToSpeech实例保持强引用(因为它是其外部类),而本机引用则保持参考Connection

解决此问题的一种方法是使用应用程序上下文而不是活动上下文来绑定TTS服务。

initializeTextToSpeech()中,而不是:

    mtts = TextToSpeech(this, TextToSpeech.OnInitListener { status ->

尝试一下:

    mtts = TextToSpeech(getApplicationContext(), TextToSpeech.OnInitListener { status ->
© www.soinside.com 2019 - 2024. All rights reserved.