Контекст приложения для SharedPreferences?

Могу ли я использовать ApplicationContext для работы с SharedPreferences и запускать, например, RemoteService?

По логике, я думаю, что могу. Существуют ли какие-либо нюансы в таком подходе?

Ответы

Ответ 1

Вы должны использовать Activity или Service Context, т.е. 'this', если у вас нет ясной и сильной причины. Используйте ApplicationContext только в том случае, если вам явно нужна ссылка на глобальное состояние вашего приложения.

Из документов API разработчиков Android в ContextWrapper's getApplicationContext() метод:

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

и

с использованием ApplicationContext (...) [в отличие от, например, контекст активности или службы] может легко привести к серьезным утечкам, если вы забудете отменить регистрацию, отменить привязку и т.д.

Например, чтобы получить SharedPreferences в Activity, например, измените данные, отображаемые пользователю, используйте this.getSharedPreferences(...), так как нет четкой причины, по которой вам нужно будет использовать жизненный цикл приложения. То же самое, в Service, используйте this.getSharedPreferences(...). (Обратите внимание, что Activity и Service являются Контекстами. Они косвенно расширяют android.content.Context)

CommonsWare написал подробный ответ: Когда вызывать контекст активности или контекст приложения?, где он делает случай, что вызов getApplicationContext() "is almost always wrong" и очертания несколько исключений, когда его использовать:

  • привязка к службе из Activity.
  • что-то должно быть привязано к контексту с глобальной областью.

CommonsWare также ссылается на ответ разработчиком Android Framework Engine Dianne Hackborn:

Первое правило, которое я бы вам дал: если вы не знаете, зачем вам [контекст приложения], вам, вероятно, он не нужен (...) Единственный раз, когда вы хотите использовать getApplicationContext(), - это когда вы нужен Контекст, который существует вне жизненного цикла класса Activity (или другого компонента).

Дополнительные ответы на один и тот же вопрос с обсуждениями, относящимися к ApplicationContext:

Ответ 2

поскольку Gunnar Karlsson упомянул ContextWrapper getApplicationContext(), его довольно ясно, что вы должны использовать только Activity или Service Контекст, чтобы зарегистрировать/отменить регистрацию вашего ресивера, привязать/развязать свои службы (если это действительно не требуется для регистрации со статическими данными, а не с конкретным компонентом), чтобы избежать неопределенной утечки памяти и быть безопасным даже если вы иногда забываете отменить регистрацию, система очистит его для вас предупреждениями.

Но для getSharedPreferences(...) вы всегда можете использовать любые ApplicationContext или Context без заминки. причина, было ясно указано

Для любого конкретного набора предпочтений (здесь SharedPreferences) существует один экземпляр этот класс, который разделяет все клиенты.

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

Обратите внимание, что регистрация получателя через контекст приложения будет поддерживаться как глобальное состояние, связанное с вашим приложением. Поэтому он никогда не будет очищен для вас.

Пожалуйста, поправьте меня, если я ошибаюсь.

Надеюсь, это поможет вам.

Ответ 3

Да, вы можете использовать getApplicationContext() для этого. Вы можете использовать getApplicationContext() везде, где вы используете getBaseContext() или ключевое слово this, когда находитесь в Activity или Service, за исключением очень конкретных случаев, например, при добавлении представлений или диалоговых окон в пользовательский интерфейс.

Здесь - отличная статья о том, что такое Контекст и что делает, что я определенно рекомендую пройти.