Свободный от утечки памяти синглтон с контекстом - PullRequest
0 голосов
/ 28 января 2019

Я пытаюсь реализовать следующий шаблон синглтона: SingletonClass.getInstance(context).callMethod()

Хотя существует множество учебных пособий, объясняющих, как создавать синглеты в Kotlin, ни один из них не затрагивает тот факт, что удержание contextв статическом поле приведет к утечке памяти в Android.

Как создать вышеуказанный шаблон без утечки памяти?

Обновление:

Вот моя реализация решения CommonsWare # 2.Я использовал Koin.

Класс Singleton:

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()

}

Ответы [ 4 ]

0 голосов
/ 29 января 2019

Я бы не сохранял контекст в SingletonClass, я просто передавал бы контекст каждому методу класса через внедрение зависимостей.Примерно так:

SingletonClass.callMethod(context)

Определите «статический» метод в объекте-компаньоне следующим образом:

 companion object {
        fun callMethod(context: Context) {
            // do Something
        }
    }

Затем вызовите его из своей деятельности с помощью:

SingletonClass.callMethod(this)

Надеюсь, что это поможет:)

0 голосов
/ 28 января 2019

если вы должны создать синглтон-класс с включенным контекстом, вы можете сделать это следующим образом.Это поможет.В этом случае ваш контекст будет сбрасываться в каждом действии, когда вы вызываете 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;
  }
}
0 голосов
/ 28 января 2019

Когда вы вызываете getInstance() в первый раз, Context, который вы передаете этой функции, сохраняется навсегда.Таким образом, контекст в последующих getInstance() вызовах не имеет никакого отношения к этому.Я никогда не сохраняю это Context.

Вот что я делаю:

Создайте object в Kotlin и инициализируйте объект контекстом, как только приложение запустится.Вместо сохранения контекста я выполняю любую операцию с этим контекстом.

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()

Вы можете сделать это, если вам не нужна ссылка на Context каждый раз, когда вы выполняете что-то с классом Singleton.

0 голосов
/ 28 января 2019

Вариант № 1: getInstance(Context) вызовите applicationContext на входящем в комплект Context и удерживайте его.Application синглтон создается, когда ваш процесс существует и живет в течение всего процесса.Это предварительно утечка;Вы не можете утечь его дальше.

Вариант № 2: Избавьтесь от getInstance() и настройте некоторую форму внедрения зависимостей (Dagger 2, Koin и т. д.).Существуют рецепты для этих структур DI, чтобы они поставляли синглтон Application синглетам, которые они создают и внедряют вниз по течению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...