Подтвердить что ты не робот

Безопасно ли сохранять контекст приложения в статической переменной в Android?

Я знаю, что использование статических переменных на Android довольно рискованно, особенно если вы ссылаетесь на их действия. Однако, если у меня есть класс, расширяющий приложение (позвольте этому классу "App" ), безопасно ли ссылаться на экземпляр этого класса?

Если да, то безопасно ли для любого другого класса иметь какую-либо ссылку на контекст приложения? Я имею в виду, может ли быть утечка памяти, если у меня есть ссылка на контекст приложения в любом классе?

Цель состоит в том, что независимо от того, в какой области я работаю, я всегда могу получить ссылку на контекст приложения. Я считаю, что это безопасно, поскольку, если система закрывает приложение, статическая переменная также исчезает до следующего запуска приложения снова, что снова инициализирует статическую переменную.

Кроме того, это не так важно, но если я использую несколько процессов, получаю ли я совершенно разные ссылки на класс App для каждого процесса?

Как пример кода, вот о чем я думаю:

public class App extends Application
{
    private static Context _appContext;

    @Override
    public void onCreate()
    {
        super.onCreate();
        _appContext = this;
    }

    public static Context getAppContext()
    {
        return _appContext;
    }
}
4b9b3361

Ответ 1

Безопасно ли сохранять контекст приложения в статической переменной?

В настоящее время да, это кажется безопасным, хотя я бы не имел getAppContext() return Context, а вместо этого возвращал App или Application.

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

Как говорится в аббревиатуре, YMMV.: -)


ИЗМЕНИТЬ

если это так, безопасно ли для любого другого класса иметь какую-либо ссылку на контекст приложения?

Я понятия не имею, что вы подразумеваете под "безопасным" здесь.

но если я использую несколько процессов, я получаю совершенно разные ссылки на класс App для каждого процесса, правильно?

Если вы используете несколько процессов, вам следует ударить форелью. Но да, вы должны получить разные экземпляры App для каждого процесса.

Ответ 2

Это должно быть безопасно. Кроме того, следующее примечание из API-документов может иметь отношение к вам:

Как правило, нет необходимости в подклассе Application. В большинстве случаев, статические синглеты могут обеспечивать такую ​​же функциональность в более модульной путь. Если ваш singleton нуждается в глобальном контексте (например, для регистрации широковещательные приемники), функция для ее получения может быть предоставлена Контекст, который внутренне использует Context.getApplicationContext(), когда сначала построим синглтон.

Ответ 3

Это безопасно сделать в Application#onCreate(), потому что Application создается перед любым действием. Если ваше приложение будет убито в фоновом режиме, экземпляр Application будет воссоздан, и ваш глобальный будет установлен до запуска любого действия.

Важно отметить, что вы никогда не должны устанавливать глобальные переменные из активности. Если вы это сделаете, ваше приложение может выйти из строя следующим образом:

  • Установить глобальную активность A
  • Перейдите к действию B
  • Приложение переходит в фоновый режим
  • Рамка убивает приложение и процесс
  • Приложение восстановлено
  • Framework создает активность B. Действия в backstack не создаются до тех пор, пока вы не вернетесь к ним, поэтому глобальное не будет установлено!
  • Активность B пытается использовать глобальные и стрелы... NullPointerException

Ответ 4

Интересный комментарий появился из Studio, когда я убирал неприятные статические контексты:

"Это утечка (а также прерывает Instant Run).

Итак, с запуском Instant Run, мы имеем дело с тем, что разработчики Android не планируют сохранять статические переменные. В то время как мгновенный запуск еще не включен в мою повестку дня, полезно знать, что существует конкретный пример, где это не только плохая практика, но и прецедент, где он ошибочен, идентифицирован.

Ответ 5

Это предупреждение при создании Context context; в андроид-студии:

Не размещайте классы контекста Android в статических полях; это утечка памяти, а также прерывает Instant Run.

Статическое поле будет утечка контекстов.

Нестатические внутренние классы имеют неявную ссылку на их внешний класс.

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

Классы ViewModel никогда не должны указывать на представления или контексты без приложения.