0

在我的 Android 应用程序中,我需要为服务类创建带有参数的单例:

class AndroidFileUtil2 private constructor(newContext: Context) {

    init {
        context = newContext
        if (BuildConfig.DEBUG)
            Log.d(TAG, "CONSTRUCTOR: context = $context")
    }

    companion object {
        private var instance: AndroidFileUtil2? = null
        private lateinit var context: Context

        private val TAG = AndroidFileUtil2::class.java.name

        @Synchronized
        fun getInstance(context: Context): AndroidFileUtil2 {
            if (instance == null) {
                instance = AndroidFileUtil2(context)
            }
            return instance as AndroidFileUtil2
        }

        fun getTest() {
            if (BuildConfig.DEBUG)
                Log.d(TAG, "getTest(): context_cacheDir = ${context.cacheDir}")
        }
    }

}

并像这样使用:

class Main : Application() {
  override fun onCreate() {
      super.onCreate()
      AndroidFileUtil2.getInstance(appContext)
      AndroidFileUtil2.getTest()
    }

}

它工作正常。当我称它为AndroidFileUtil2.getTest()我的应用程序的成功打印缓存目录时。像这样:

getTest(): context_cacheDir = /data/user/0/com.myproject.client.debug/cache

好的。

但在 IDE 上,我收到这样的警告:

Do not place Android context classes in static fields. This is a memory leak

在这一行:

private lateinit var context: Context

如何在我的单身课程中解决此警告?

4

2 回答 2

0

此错误是针对泛型Context的,因为 aContext可能是任何短期组件,例如 Activity 或 Service。它不会给你一个错误Application,因为应用程序在你的应用程序的整个生命周期中都存在。而且由于 anApplication是 a Context,您几乎可以将它用于您将使用 a Contextfor 的任何东西,因此您可以更改变量类型Application以避免警告并防止任何泄漏的风险。

所以制作lateinit varan Application,并将Application参数类型设为getInstance()

classes ActivityServiceAndroidViewModelall 具有application可用于传递给getInstance()函数的属性。

但是除了避免 Lint 警告之外,还可以AndroidFileUtil2使用 make 的构造函数Application来代替,Context因为它是一个单例。Lint 不够复杂,无法识别并警告您,但正如现在定义的那样,AndroidFileUtil2静态引用与静态泛型Context引用一样具有导致泄漏的风险。

于 2020-01-30T14:57:58.377 回答
0

你应该setContext在你的静态部分使用方法检查这里: Access application context in companion object in kotlin

于 2020-01-30T12:07:44.943 回答