Разница между getContext(), getApplicationContext(), getBaseContext() и "this"

В чем разница между getContext(), getApplicationContext(), getBaseContext() и "this"?

Хотя это простой вопрос, я не могу понять основную разницу между ними. Если возможно, приведите несколько простых примеров.

+531
17 мая '12 в 18:07
источник поделиться
8 ответов
  • View.getContext(): возвращает контекст, в котором в настоящее время выполняется представление. Обычно текущая активная активность.

  • Activity.getApplicationContext(): возвращает контекст для всего приложения (процесс, в котором все действия запущены внутри из). Используйте это вместо текущего контекста активности, если вам нужно контекст, привязанный к жизненному циклу всего приложения, а не только текущая деятельность.

  • ContextWrapper.getBaseContext(): если вам нужен доступ к контексту из другого контекста, вы используете ContextWrapper. Контекст, на который ссылается внутри, что ContextWrapper доступен через getBaseContext().

+507
17 мая '12 в 18:15
источник

Большинство ответов уже охватывают getContext() и getApplicationContext(), но getBaseContext() редко объясняется.

Метод getBaseContext() применим только тогда, когда у вас есть ContextWrapper. Android предоставляет класс ContextWrapper, созданный вокруг существующего Context, используя:

ContextWrapper wrapper = new ContextWrapper(context);

Преимущество использования ContextWrapper заключается в том, что он позволяет вам "изменять поведение без изменения исходного контекста". Например, если у вас есть действие под названием myActivity, то можно создать View с другой темой, чем myActivity:

ContextWrapper customTheme = new ContextWrapper(myActivity) {
  @Override
  public Resources.Theme getTheme() { 
    return someTheme;
  }
}
View myView = new MyView(customTheme);

ContextWrapper действительно эффективен, потому что он позволяет вам отменить большинство функций, предоставляемых Context, включая код для доступа к ресурсам (например, openFileInput(), getString()), взаимодействовать с другими компонентами (например, sendBroadcast(), registerReceiver()), запрашивает разрешения (например, checkCallingOrSelfPermission()) и разрешает расположение файловой системы (например, getFilesDir()). ContextWrapper действительно полезен для решения проблем с конкретными устройствами/версиями или для применения одноразовых настроек к компонентам, таким как представления, требующие контекста.

Метод getBaseContext() может использоваться для доступа к "базовому" контексту, который обтекает ContextWrapper. Вам может потребоваться доступ к "базовому" контексту, если вам нужно, например, проверить, есть ли его Service, Activity или Application:

public class CustomToast {
  public void makeText(Context context, int resId, int duration) {
    while (context instanceof ContextWrapper) {
      context = context.baseContext();
    }
    if (context instanceof Service)) {
      throw new RuntimeException("Cannot call this from a service");
    }
    ...
  }
}

Или, если вам нужно вызвать "развернутую" версию метода:

class MyCustomWrapper extends ContextWrapper {
  @Override
  public Drawable getWallpaper() {
    if (BuildInfo.DEBUG) {
      return mDebugBackground;
    } else {
      return getBaseContext().getWallpaper();
    }
  }
}
+77
13 февр. '17 в 18:24
источник

getApplicationContext(). Возвращает контекст для всех действий, выполняемых в приложении.

getBaseContext(). Если вы хотите получить доступ к Контексту из другого контекста в приложении, к которому вы можете получить доступ.

getContext() - возвращает контекстное представление только текущей текущей активности.

+38
10 мар. '14 в 8:51
источник

Context предоставляет информацию о Actvity или Application для вновь созданных компонентов.

Соответствующий Context должен быть предоставлен вновь созданным компонентам (контекст приложения или контекст активности)

Так как Activity является подклассом Context, можно использовать this для получения этого контекста активности

+28
02 мар. '13 в 13:28
источник

Вопрос "что такое контекст" является одним из самых сложных вопросов в Android-юниверсе.

Контекст определяет методы доступа к системным ресурсам, извлечения статических активов приложения, проверки разрешений, выполнения манипуляций пользовательского интерфейса и многих других. По сути, Context является примером анти-шаблона Бога-объекта в производстве.

Когда дело доходит до того, какой тип Context мы должны использовать, он становится очень сложным, потому что, за исключением объекта God Object, дерево иерархии подклассов Context жестоко нарушает принцип замещения Лискова.

Это сообщение в блоге пытается обобщить применимость классов Context в разных ситуациях.

Позвольте мне скопировать основную таблицу из этой публикации для полноты:

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | Application | Activity | Service | ContentProvider | BroadcastReceiver |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
| Show a Dialog              | NO          | YES      | NO      | NO              | NO                |
| Start an Activity          | NO¹         | YES      | NO¹     | NO¹             | NO¹               |
| Layout Inflation           | NO²         | YES      | NO²     | NO²             | NO²               |
| Start a Service            | YES         | YES      | YES     | YES             | YES               |
| Bind to a Service          | YES         | YES      | YES     | YES             | NO                |
| Send a Broadcast           | YES         | YES      | YES     | YES             | YES               |
| Register BroadcastReceiver | YES         | YES      | YES     | YES             | NO³               |
| Load Resource Values       | YES         | YES      | YES     | YES             | YES               |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
  1. Приложение может начать работу здесь, но для этого требуется создать новую задачу. Это может соответствовать конкретным вариантам использования, но может создавать нестандартные поведения в обратном стеке в вашем приложении и, как правило, не рекомендуется или считается хорошей практикой.
  2. Это законно, но инфляция будет производиться с помощью темы по умолчанию для системы, на которой вы работаете, а не на то, что определено в вашем приложении.
  3. Допускается, если приемник имеет значение null, которое используется для получения текущего значения липкой трансляции, на Android 4.2 и выше.

- скриншот

+21
09 мар. '17 в 16:31
источник

Часть UML-диаграммы контекста

enter image description here

+10
12 июн. '18 в 9:46
источник

Из этого docs

Я понял, что вы должны использовать:

Попробуйте использовать контекстное приложение вместо контекстной активности

+1
15 апр. '14 в 6:54
источник

getApplicationContext()

это используется для уровня приложения и относится ко всем действиям.

getContext() и getBaseContext()

скорее всего, один и тот же. В этом выражается только текущая активность, которая является живой.

это

всегда ссылается на текущий объект класса.

0
11 авг. '17 в 11:46
источник

Посмотрите другие вопросы по меткам или Задайте вопрос