Приводит ли хранение ссылки на Application в static поле внутри себя к утечки памяти?

Есть желание при запуске приложения хранить ссылку в переопределённом Application на саму себя в static поле для удобства доступа к актуальному контексту, конфигурации и id ресурсов.

Насколько это критично для утечки памяти?

public class MainApplication extends Application {

/**
 * Название главных настроек
 */
private static final String SETTINGS_NAME = "erfecdcdvqefvwe";

//Для реализации ссылки на приложение
private static MainApplication instance;


/**
 * Стартует при зауске приложения
 */
@Override
public void onCreate() {
    super.onCreate();

    //Сохраняем ссылку на этот класс
    instance = this;
}


/**
 * Вернуть ссылку на приложение
 */
public static MainApplication getInstance(){
    return instance;
}

/**
 * Главные настройки приложения
 */
public static SharedPreferences getSettings(){
    return getInstance().getSharedPreferences(SETTINGS_NAME, MODE_PRIVATE);
}

public static Context getAppContext(){
    return getInstance().getApplicationContext();
}

/**
 * Получить цвет из ресурсов
 */
public static ColorDrawable getResColor(int resId){
    return new ColorDrawable(ContextCompat.getColor(MainApplication.getInstance().getApplicationContext(), resId));
}


/**
 * Пиксели в DP
 */
public   static float dpFromPx(float px) {
    return px/ getAppContext()
            .getResources()
            .getDisplayMetrics()
            .density;
}

/**
 * DP в пиксели
 */
public static float pxFromDp(float dp) {
    return dp * getAppContext()
            .getResources()
            .getDisplayMetrics()
            .density;
}

}


Ответы (3 шт):

Автор решения: Sergei Buvaka

Не критично. Application живёт в течении всего приложения и умирает только когда умирает приложение. Application не может существовать в более чем одном экземпляре, а значит никаких утечек памяти быть не может.

Недостатком является то, что нет гарантии, что не статический onCreate() будет вызван до того, как какой-то статический код инициализации попытается получить ваш объект Context. Это означает, что ваш вызывающий код должен быть готов к работе с null значениями.

Тем не менее даже в серьезных проектах этот подход используется. И в целом это очень распространенное решение.

→ Ссылка
Автор решения: Aziz Umarov

А как иначе если существует паттерн Singleton. Советую ознакомиться с ним.

Его идея проста. Создание единственного экземпляра для класса и хранение его ссылки в статической переменной. Так как утечек не наблюдается и таковым минусом он не обладает советую присмотреться на этот паттерн и сделать выводы.

 public class Singleton {

  
  private static Singleton instance;
  private Singleton () {}

  public static synchronized Singleton getInstance() {
   if (instance == null) {
   instance = new Singleton();
  }
  return instance;
 }
}
→ Ссылка
Автор решения: Георгий Чеботарев

Все хорошо, так делать можно, если есть потребность.

Извините, но я дам вам дополнительный callback по коду, в конце концов на то сообщества и нужны:

  • класс Application должен быть пустым. Никаких статических методов общего назначиеня(dpFromPx, pxFromDpб getResColor) - выносите их в отдельный классы. В Application должны быть только инициализации синглтонов (за редким исключением, вроде Thread.UncaughtExceptionHandler).

  • переходите на Kotlin. Не вижу ни одной причины учиться писать под android на java. Kotlin не так сильно отличается от Java, чтобы его бояться. Это даст вам множество синтаксического сахара и полезного опыт разработки.

  • пишите комментарии на английском. Кто бы не смотрел код после вас - точно поймет коментарии к коду, а заодно вы подтянете язык. Плюс, в какой бы среде или редакторе в будущем вы не откроете свой код латиница точно отобразиться верно.

Надеюсь, вы поизитвно относитесь к конструктивной критике.

→ Ссылка