web-dev-qa-db-ja.com

Kotlin Androidで「このAsyncTaskクラスは静的である必要があり、リークが発生する可能性があります」への正しいアプローチは何ですか?

Java Androidで_This class should be static or leaks might occur_を扱う多くの質問があります。

このハンドラークラスは静的である必要があります。そうしないと、リークが発生する可能性があります:IncomingHandler

このHandlerクラスは静的である必要があります。そうしないと、リークが発生する可能性があります:AsyncQueryHandler

このAsyncTaskクラスは静的である必要があります。そうしないと、リークが発生する可能性があります(匿名のAndroid.os.AsyncTask)

警告は、内部クラスが外部クラスへの暗黙の参照を保持しているため、外部クラスがGCされないようにするためです。解決策は、クラスが静的であると宣言する必要があるという警告自体にあります。

ただし、解決策はJava固有です。kotlinにstatic修飾子がない場合、最も近いものは コンパニオンオブジェクト であり、コンパニオンオブジェクトはそれは「アウタークラス」です。

以下は私の[失敗した]試みとコメントです

_class MyActivity : AppCompatActivity(), MyListener {

    companion object {
        class Attempt3Task(val callback: MyListener) : AsyncTask<Unit, Unit, Unit>() {
            override fun doInBackground(vararg params: Unit?) {
                TODO("")
            }

            override fun onPostExecute(result: Unit?) {
                callback.updateUi()
            }
        }
    }

    inner class Attempt2Task : AsyncTask<Unit, Unit, Unit> () {
        override fun doInBackground(vararg params: Unit?) {
            TODO("
        }
    }

    // Gives warning "This AsyncTask class should be static or leaks might occur"
    val attempt_1 = object: AsyncTask<Unit, Unit, Unit>() {
        override fun doInBackground(vararg params: Unit?) {
            TODO("")
        }
    }

    // Does not give warning but, as far as I can tell, is conceptually same as attempt_1
    val attempt_2 = Attempt2Task()

   // Does not give warning but companion object does have reference to the activity, no?
    val attempt_3 = Attempt3Task(this)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }
}
_

Try2とattempt3に関するアサーションは、リンターの警告がなくてもコードがリークしていることを修正していますか?

漏れを防ぐためにどのようなオプションが必要ですか?コールバックするためにWeakReferenceのメンバーを持つプレーンな古いトップレベルのclass MyTask : AsyncTask<Unit, Unit, Unit> ()に解決する必要がありますか?

14
user2829759

アクティビティクラスの外にAsyncTaskクラス宣言がないのはなぜですか?

Kotlinでは、アクティビティと同じファイルにある可能性がありますが、Activityクラスのすぐ上/下にあります。

そうすれば、非表示の参照に関する問題はありません。

また、AsyncTask内のリスナーへのWeakReferenceを保持するようにしてください。

そうは言っても、私によれば、AsyncTaskは過去のものであり、RxJava、コルーチン、ローダーなど、より新しい代替手段を使用する必要があります。

1