我正在尝试实现以下单例模式:SingletonClass.getInstance(context).callMethod()
尽管有各种各样的教程说明了如何在Kotlin中制作单身人士,但没有一个能解决这样一个事实:在静态字段中持有context
会导致Android中的内存泄漏。
如何创建上述模式而不造成内存泄漏?
更新:
这是我对CommonsWare解决方案2的实现。我用过Koin。
单班:
class NetworkUtils(val context: Context) {
}
应用程序类:
class MyApplication : Application() {
val appModule = module {
single { NetworkUtils(androidContext()) }
}
override fun onCreate() {
super.onCreate()
startKoin(this, listOf(appModule))
}
}
活动分类:
class MainActivity : AppCompatActivity() {
val networkUtils : NetworkUtils by inject()
}
答案 0 :(得分:7)
选项#1:让getInstance(Context)
在提供的applicationContext
上呼叫Context
并按住。 Application
单例是在您的流程存在并在该流程的生命期内存在的时候创建的。它是预先泄漏的;您不能再泄漏它了。
选项2:摆脱getInstance()
并设置某种形式的依赖项注入(Dagger 2,Koin等)。这些DI框架有一些方法可以使它们向其创建并向下游注入的单例提供Application
单例。
答案 1 :(得分:0)
首次调用getInstance()
时,传递给此功能的Context
将被永久保存。因此,进一步的getInstance()
调用中的上下文在那里没有任何关系。我从不保存此Context
。
这就是我正在做的:
在Kotlin中创建一个object
,并在应用启动后立即使用上下文初始化该对象。我不存储上下文,而是执行该上下文所需的任何操作。
object PreferenceHelper {
private var prefs: SharedPreferences? = null
fun initWith(context: Context){
if(prefs == null) this.prefs = context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
}
fun someAction(){ .... }
}
并在Application
类中:
class MyApp: Application(){
override fun onCreate(){
PreferenceHelper.initWith(this)
}
}
以及随后在应用中的任何地方:
PreferenceHelper.someAction()
如果每次使用Singleton类执行某些操作时都不需要引用Context
,则可以执行此操作。
答案 2 :(得分:0)
我不会将上下文存储在SingletonClass中,我只会通过依赖注入将上下文传递给类的每个方法。 像这样:
SingletonClass.callMethod(context)
在随播对象中定义“静态”方法,如下所示:
companion object {
fun callMethod(context: Context) {
// do Something
}
}
然后通过以下活动从您的活动中调用它:
SingletonClass.callMethod(this)
希望它会有所帮助:)
答案 3 :(得分:-1)
如果必须创建包含上下文的单例类,则可以这样进行。这会有所帮助。在这种情况下,当您调用getInstance(context)时,您的上下文将在每个活动中重置。
public class MyClass {
private Context context;
public static getInstance(Context context){
if(instance ==null)
instance = new MyClass();
instance.setContext(context);
return instance;
}
public void setContext(Context context){
this.context = context;
}
}