В чем разница между getContext()
, getApplicationContext()
, getBaseContext()
и " this
«?
Хотя это простой вопрос, я не могу понять принципиальную разницу между ними. Пожалуйста, приведите несколько простых примеров, если это возможно.
В чем разница между getContext()
, getApplicationContext()
, getBaseContext()
и " this
«?
Хотя это простой вопрос, я не могу понять принципиальную разницу между ними. Пожалуйста, приведите несколько простых примеров, если это возможно.
Ответы:
View.getContext()
Возвращает контекст, в котором в данный момент выполняется представление. Обычно текущая активная активность.
Activity.getApplicationContext()
Возвращает контекст для всего приложения (процесс, внутри которого выполняются все действия). Используйте это вместо текущего контекста Activity, если вам нужен контекст, связанный с жизненным циклом всего приложения, а не только с текущим Activity.
ContextWrapper.getBaseContext()
: Если вам нужен доступ к контексту из другого контекста, вы используете ContextWrapper. Контекст, на который ссылается внутри этого ContextWrapper, доступен через getBaseContext ().
this
и getContext()
не всегда одинаковы, например, в классе Activity, вы можете использовать, this
потому что Activity
наследует, Context
но метод getContext()
не в Activity
классе. @mikedroid @KCRaju
Большинство ответов уже охватывают getContext()
и getApplicationContext()
но getBaseContext () редко объяснено.
Метод getBaseContext()
актуален только тогда, когда у вас есть ContextWrapper
. Android предоставляет ContextWrapper
класс, который создается с Context
использованием существующего :
ContextWrapper wrapper = new ContextWrapper(context);
Преимущество использования a 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();
}
}
}
ContextWrapper
- одно из худших решений, когда-либо принятых разработчиками платформы Android. Когда они поняли, что создали целое семейство Объектов Бога, вместо того, чтобы делать правильные вещи и рефакторинг кода в сторону Единой Ответственности, они добавили уродливый хак, который позволил изменить поведение контекста путем углубления дерева наследования. Плохая программная инженерия в самом уродливом виде. Что касается нас, разработчиков, ИМХО , никто никогда не должен использовать getBaseContext()
или ContextWrapper
. Если вы делаете - это огромный «кодовый запах».
CustomToast
код. ) : ))))))
getApplicationContext () - возвращает контекст для всех действий, выполняемых в приложении.
getBaseContext () - если вы хотите получить доступ к контексту из другого контекста в приложении, вы можете получить к нему доступ.
getContext () - возвращает контекстное представление только текущей текущей активности.
Вопрос «что такое контекст» является одним из самых сложных вопросов во вселенной Android.
Контекст определяет методы, которые обращаются к системным ресурсам, извлекают статические активы приложения, проверяют разрешения, выполняют манипуляции с пользовательским интерфейсом и многое другое. По сути, Context
это пример анти-паттерна God Object в производстве.
Когда дело доходит до того, какой тип Context
мы должны использовать, это становится очень сложным, потому что, кроме того, что он является Объектом Бога, дерево иерархии 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 | +----------------------------+-------------+----------+---------+-----------------+-------------------+
- Приложение МОЖЕТ запустить Отсюда Действие, но оно требует создания новой задачи. Это может соответствовать конкретным случаям использования, но может привести к нестандартному поведению бэк-стека в вашем приложении и, как правило, не рекомендуется или считается хорошей практикой.
- Это законно, но инфляция будет выполняться с темой по умолчанию для системы, в которой вы работаете, а не с тем, что определено в вашем приложении.
- Разрешено, если получатель имеет нулевое значение, которое используется для получения текущего значения липкой трансляции, на Android 4.2 и выше.
Context
предоставляет информацию о Actvity
илиApplication
только что созданным компонентам.
Соответствующее Context
должно быть предоставлено вновь созданным компонентам (будь то контекст приложения или контекст действия)
Так Activity
как это подкласс Context
, можно использовать, this
чтобы получить контекст этой деятельности
Из этой документации
Я понял, что вы должны использовать:
Попробуйте использовать контекстное приложение вместо контекстной активности
getApplicationContext ()
это используется для прикладного уровня и относится ко всем действиям.
getContext () и getBaseContext ()
Это, скорее всего, то же самое. Эти ссылки относятся только к текущей деятельности, которая является живой.
это
всегда ссылается на текущий объект класса.
А Context
это: