我正在尝试实现以下单例模式: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()
}
选项#1:让getInstance(Context)
在提供的applicationContext
上调用Context
并持有它。 Application
单身人士是在你的过程过程中为这个过程的生命而生活的。它是预先泄露的;你不能进一步泄漏它。
选项#2:摆脱getInstance()
并设置某种形式的依赖注入(Dagger 2,Koin等)。有这些DI框架的配方,让它们将Application
单例提供给它们创建并向下游注入的单体。
当您第一次调用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
,则可以执行此操作。
我不会将上下文存储在SingletonClass中,我只是通过依赖注入将上下文传递给类的每个方法。就像是:
SingletonClass.callMethod(context)
在配对对象中定义“静态”方法,如下所示:
companion object {
fun callMethod(context: Context) {
// do Something
}
}
然后从您的活动中调用它:
SingletonClass.callMethod(this)
希望它有帮助:)
如果你必须创建包含上下文的单例类,你可以这样做。这会有所帮助。在这种情况下,当您调用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;
}
}