Вопрос по this, android – Разница между getContext (), getApplicationContext (), getBaseContext () и «этим»

494

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

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

В первом ответе отличная рецензия: / Stackoverflow.com вопросы / 1026973 / ... ky1enamic

Ваш Ответ

7   ответов
1

@ Докумен

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

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

487

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

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

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

а что насчет "этого"? CooL i3oY
На самом деле я запутался, что такое правильное определение контекста ?? Ravi
"this" и getContext () оба одинаковы KCRaju
this а такжеgetContext() не всегда одинаковы, например в классе Activity вы можете использоватьthis потому чтоActivity наследует отContext но методgetContext() не вActivity учебный класс. @mikedroid @ KCRaju nandan
+ CooL i3oY то же самое с getContext Mikey
38

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

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

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

Pls включает буквы A и B в ваше определение контекста внутри контекста, в любом ответе неясно, к какому контексту осуществляется доступ. HopefullyHelpful
28

Con,text предоставляет информацию оActvity илиApplication недавно созданным компонентам.

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

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

Где твое объяснение о baseContext? IgorGanapolsky
70

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();
    }
  }
}
Я бы сказал, что существованиеContextWrapper является одним из худших решений, когда-либо принятых разработчиками платформы Android. Когда они поняли, что создали целое семейство Объектов Бога, вместо того, чтобы делать правильные вещи и рефакторинг кода в направлении Единой Ответственности, они добавили уродливый хак, который позволил изменить поведение контекста путем углубления дерева наследования. Плохая программная инженерия в самом уродливом виде. Что касается нас, разработчиков, ИМХО никто не должен использоватьgetBaseContext() илиContextWrapper. Если вы это сделаете - это огромный «запах кода». Vasiliy
Я бы сказал, это самый важный ответ после принятого. 0leg
18

ной Android.

Context определяет методы, которые обращаются к системным ресурсам, извлекают статические активы приложения, проверяют разрешения, выполняют манипуляции с пользовательским интерфейсом и многое другое. По сути,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 и выше.

Скриншо

Отличное сообщение в блоге, на которое вы ссылались! lejonl
0

getApplicationContext ()

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

getContext () и getBaseContext ()

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

эт

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

Это почти совершенно неверно Tim Castelijns

Похожие вопросы