试图在另一个Singleton中使用Singleton类,但是不知何故它给了我内存泄漏。
我该如何改善?
这是我的单例实现示例
foreach
SecondSingletonClass块
class FirstSingletonClass(val context: Context) {
companion object {
@Volatile
private var instance: FirstSingletonClass? = null
fun getInstance(context: Context): FirstSingletonClass =
instance ?: synchronized(this) {
instance ?: FirstSingletonClass(context).also { instance = it }
}
}
private val sSingletonClass: SecondSingletonClass = Injection.provideSecondSingletonClass(context)
}
注射类
class SecondSingletonClass(val context: Context) {
companion object {
@Volatile
private var instance: SecondSingletonClass? = null
fun getInstance(context: Context): SecondSingletonClass =
instance ?: synchronized(this) {
instance ?: SecondSingletonClass(context).also { instance = it }
}
}
private val fSingletonClass: FirstSingletonClass = Injection.provideFirstSingletonClass(context)
}
因此,当我初始化属性-object Injection {
fun provideSecondSingletonClass(context: Context): SecondSingletonClass = SecondSingletonClass.getInstance(context)
fun provideFirstSingletonClass(context: Context): FirstSingletonClass = FirstSingletonClass.getInstance(context)
}
或private val sSingletonClass
时,会产生内存泄漏。但是,如果我将在功能块中的某个地方调用我的单例类,则效果很好。
有可能实现我想要的吗?还是我应该明确使用它...
答案 0 :(得分:2)
您正在此处泄漏上下文。您不应持有对Context的长期引用。相反,可以在需要它们的FirstSingletonClass和SecondSingletonClass方法中将Context作为参数。
Android Studio应该向您发出此警告:
请勿将Android上下文类放在静态字段中(静态引用SecondSingletonClass的字段上下文指向Context);这是内存泄漏(还会中断即时运行)
您的代码可以简化为:
object FirstSingletonClass {
private val sSingletonClass = SecondSingletonClass
}
object SecondSingletonClass {
private val fSingletonClass = FirstSingletonClass
}
答案 1 :(得分:1)
问题::您要将Context实例传递到Singleton中,该上下文可能是活动,服务等。这可能会使上下文泄漏。
解决方案::改为使用applicationContext
。
class FirstSingletonClass(val context: Context) {
companion object {
@Volatile
private var instance: FirstSingletonClass? = null
fun getInstance(context: Context): FirstSingletonClass =
instance ?: synchronized(this) {
instance ?: FirstSingletonClass(context.applicationContext).also { instance = it }
}
}
private val sSingletonClass: SecondSingletonClass = Injection.provideSecondSingletonClass(context)
}
class SecondSingletonClass(val context: Context) {
companion object {
@Volatile
private var instance: SecondSingletonClass? = null
fun getInstance(context: Context): SecondSingletonClass =
instance ?: synchronized(this) {
instance ?: SecondSingletonClass(context.applicationContext).also { instance = it }
}
}
private val fSingletonClass: FirstSingletonClass = Injection.provideFirstSingletonClass(context)
}