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


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

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

8 467

8 ответов:

  • View.getContext(): возвращает контекст в данный момент работает. Обычно в настоящее время активная деятельность.

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

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

большинство ответов уже крышка 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();
    }
  }
}

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

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

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

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

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

С Activity является наследником Context можно использовать this чтобы получить контекст этой деятельности

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

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

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

этот блог попытки уплотнить!--1--> применимость классов в различных ситуациях.

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

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | 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 и выше.

-скриншот

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

enter image description here

отсюда docs

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

попробуйте использовать контекст приложения, а не в контексте-активность

getApplicationContext()

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

getContext () и getBaseContext ()

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

этой

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