Приводит ли хранение ссылки на 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 шт):
Не критично. Application живёт в течении всего приложения и умирает только когда умирает приложение. Application не может существовать в более чем одном экземпляре, а значит никаких утечек памяти быть не может.
Недостатком является то, что нет гарантии, что не статический onCreate() будет вызван до того, как какой-то статический код инициализации попытается получить ваш объект Context. Это означает, что ваш вызывающий код должен быть готов к работе с null значениями.
Тем не менее даже в серьезных проектах этот подход используется. И в целом это очень распространенное решение.
А как иначе если существует паттерн 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, чтобы его бояться. Это даст вам множество синтаксического сахара и полезного опыт разработки.
пишите комментарии на английском. Кто бы не смотрел код после вас - точно поймет коментарии к коду, а заодно вы подтянете язык. Плюс, в какой бы среде или редакторе в будущем вы не откроете свой код латиница точно отобразиться верно.
Надеюсь, вы поизитвно относитесь к конструктивной критике.