如何避免单例中静态字段中的Android上下文?
在我的Android应用程序中,我需要为服务类创建带有参数的singleton:如何避免单例中静态字段中的Android上下文?,android,kotlin,Android,Kotlin,在我的Android应用程序中,我需要为服务类创建带有参数的singleton: class AndroidFileUtil2 private constructor(newContext: Context) { init { context = newContext if (BuildConfig.DEBUG) Log.d(TAG, "CONSTRUCTOR: context = $context") } co
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()
}
}
getTest(): context_cacheDir = /data/user/0/com.myproject.client.debug/cache
Do not place Android context classes in static fields. This is a memory leak
很好。当我调用AndroidFileUtil2.getTest()
时,我成功地打印了我的应用程序的缓存目录。Smt是这样的:
class Main : Application() {
override fun onCreate() {
super.onCreate()
AndroidFileUtil2.getInstance(appContext)
AndroidFileUtil2.getTest()
}
}
getTest(): context_cacheDir = /data/user/0/com.myproject.client.debug/cache
Do not place Android context classes in static fields. This is a memory leak
很好
但在IDE上,我收到如下警告:
class Main : Application() {
override fun onCreate() {
super.onCreate()
AndroidFileUtil2.getInstance(appContext)
AndroidFileUtil2.getTest()
}
}
getTest(): context_cacheDir = /data/user/0/com.myproject.client.debug/cache
Do not place Android context classes in static fields. This is a memory leak
在这方面:
private lateinit var context: Context
如何在我的singleton类中修复此警告?您应该在静态部分使用
setContext
方法
请点击此处:
此错误适用于一般
上下文
,因为上下文
可以是任何短期组件,如活动或服务。它不会为应用程序
提供错误信息,因为该应用程序将在应用程序的整个生命周期内运行。由于应用程序
是一个上下文
,您几乎可以将其用于上下文
的任何内容,因此您可以将变量类型更改为应用程序
,以避免警告并防止任何泄漏风险
因此,将lateinit变量
设置为应用程序
,并将应用程序
设置为getInstance()
的参数类型
类Activity
、Service
和AndroidViewModel
都有application
属性,可以用来传递到getInstance()
函数中
但是除了避免Lint警告之外,由于它是一个单例,因此使AndroidFileUtil2
的构造函数也使用应用程序而不是上下文
是合适的。Lint不够复杂,无法识别并警告您,但正如现在定义的那样,AndroidFileUtil2
静态引用与静态泛型上下文
引用具有相同的泄漏风险