Різниця між контекстом діяльності та контекстом програми


233

Це мене натрапило, я використовував це в Android 2.1-r8 SDK:

ProgressDialog.show(getApplicationContext(), ....);

а також в

Toast t = Toast.makeText(getApplicationContext(),....);

використання getApplicationContext()збоїв як ProgressDialogіToast .... що призводить мене до цього питання:

Які фактичні відмінності між контекстом діяльності та контекстом програми, незважаючи на поділ формулювання "Контекст"?


Це те , що я знайшов stackoverflow.com/questions/1561803 / ... ....
t0mm13b

14
Це повинно допомогти з'ясувати деякі речі: контекст, який контекст?
toobsco42

Відповіді:


250

Вони обидва випадки контексту , але екземпляр програми прив'язаний до життєвого циклу програми, тоді як екземпляр діяльності прив'язаний до життєвого циклу діяльності. Таким чином, вони мають доступ до різної інформації про середовище програми.

Якщо ви читаєте документи на getApplicationContext це зазначає, що ви повинні використовувати це лише в тому випадку, якщо вам потрібен контекст, життєвий цикл якого відокремлений від поточного контексту. Це не стосується жодного з ваших прикладів.

У контексті Діяльності, мабуть, є деяка інформація про поточну діяльність, необхідну для завершення цих дзвінків. Якщо ви покажете точне повідомлення про помилку, можливо, зможете вказати на те, що саме воно потребує.

Але загалом використовуйте контекст діяльності, якщо у вас немає вагомих причин цього не робити.


1
Я отримав "java.lang.reflect.InvocationTargetException" при використанні getApplicationContext, що досить цікаво, коли я змінився this, він не вийшов з ладу і працює так, як очікувалося .... так що якщо вони обидва випадки контексту, чому один не працює, і інший робить? Ця інформація буде
корисною

2
Мені потрібно побачити повний стек-тракт виключення, щоб мати можливість сказати що-небудь. Однак, як я вже сказав, контекстні випадки мають різну інформацію. Імовірно, для відображення діалогового вікна або тостів потрібна інформація про активність, яку має лише екземпляр діяльності.
Шеріл Симон

74
Я б сказав, використовуйте контекст програми, якщо у вас немає занадто вагомих причин (тобто для діалогів або тостів). Досить легко натрапити на витоки пам’яті, використовуючи контексти діяльності в різних ситуаціях, тому краще бути безпечним :) android-developers.blogspot.com/2009/01/…
Дорі

10
Дейв Сміт опублікував дуже хороший запис у блозі для розуміння використання контексту, дивіться тут . Переконайтесь, що ви також читали коментарі!
ChrLipp

1
Вся справа в тому, що навіть Діанна Хакборн рекомендує використовувати контекст діяльності. stackoverflow.com/questions/5228160/… Але вона, здається, не зовсім впевнена в цьому.
JacksOnF1re

178

Я вважав цю таблицю супер корисною для вирішення, коли використовувати різні типи контекстів:

введіть тут опис зображення

  1. Додаток МОЖЕ розпочати діяльність звідси, але для цього потрібно створити нове завдання. Це може підходити до конкретних випадків використання, але може створювати нестандартне поведінку заднього стека у вашій програмі, і, як правило, не рекомендується або вважається хорошою практикою.
  2. Це законно, але інфляція буде здійснена за темою за замовчуванням для системи, в якій ви працюєте, а не тієї, що визначена у вашій програмі.
  3. Дозволено, якщо приймач недійсний, який використовується для отримання поточного значення липкої трансляції, на Android 4.2 і вище.

Оригінальна стаття тут .



як щодо отримання ресурсів? я думаю, вам краще додати його до свого столу. і ви можете отримати доступ до ресурсів у контексті програми.
Амір Зіараті

Ми можемо розпочати діяльність з контексту програми
Duy Phan

Статтю також можна знайти тут: wundermanthompsonmobile.com/2013/06/context
Lifes

34

Очевидно, це недолік дизайну API. По-перше, контекст діяльності та контекст програми - це абсолютно різні об'єкти, тому параметри методу, де використовується контекст, повинні використовуватися ApplicationContextабо Activityбезпосередньо, замість того, щоб використовувати батьківський клас Контекст. По-друге, doc повинен вказати, який контекст використовувати або не прямо.


25
Повністю згоден. Google скинув м'яч на цьому. Це повний безлад.
Søren Boisen

@ SørenBoisen android sdk - це повний безлад
CommonSenseCode

Вони усвідомлюють безлад, і впевнені, що намагаються виправити стільки, скільки зможуть.
пасигнатура

15

Причиною, на яку я думаю, є те, що ProgressDialogпов’язано з діяльністю, яка підсилює те ProgressDialog, що діалог не може залишатися після того, як активність знищується, тому її потрібно передавати this(ActivityContext), яка також знищується при дії, тоді як ApplicationContext залишається навіть після того, як активність отримує знищено.


3

Використовуйте getApplicationContext (), якщо вам потрібно щось прив'язане до контексту, що саме по собі матиме глобальну сферу застосування.

Якщо ви використовуєте Activity, то новий екземпляр Activity матиме посилання, яке має неявне посилання на стару Activity, а стару Activity не можна збирати сміттям.


2

Я думаю, що коли все потрібен екран, щоб показати (кнопка, діалогове вікно, макет ...), ми повинні використовувати контекстну діяльність, і все, що не потребує екрану для показу чи обробки (тост, службовий телефон, контакт ...), ми може використовувати контекст програми


1

Ви можете побачити різницю між цими двома контекстами, коли ви запускаєте додаток безпосередньо з головного екрана порівняно з тим, коли ваш додаток запускається з іншого додатка через наміри спільного використання.

Ось практичний приклад того, що означає "нестандартна поведінка заднього стека", яку згадує @CommonSenseCode:

Припустимо, у вас є два додатки, які спілкуються між собою, App1 та App2 .

Запустіть App2: MainActivity з панелі запуску. Потім від MainActivity запустіть App2: SecondaryActivity . Там, або використовуючи контекст діяльності або контекст програми, обидві дії живуть в одній задачі, і це нормально (враховуючи, що ви використовуєте всі стандартні режими запуску та прапорці намірів). Ви можете повернутися до MainActivity за допомогою натискання кнопки назад, а в останніх програмах у вас є лише одне завдання.

Припустимо, зараз ви перебуваєте в App1 та запускаєте App2: MainActivity з наміром спільного доступу (ACTION_SEND або ACTION_SEND_MULTIPLE). Потім звідти спробуйте запустити App2: SecondaryActivity (завжди зі всіма стандартними режимами запуску та прапорами намірів). Що відбувається:

  • якщо ви запускаєте App2: SecondaryActivity з контекстом програми на Android <10, ви не можете запустити всі дії в одній задачі . Я намагався з Android 7 і 8, і SecondaryActivity завжди запускається в новому завданні (я думаю, тому, що App2: SecondaryActivity запускається в контексті програми App2, але ви прийшли з App1, і ви не запустили додаток App2 безпосередньо . Можливо, під капотом андроїд розпізнає це і використовує FLAG_ACTIVITY_NEW_TASK). Це може бути добре чи погано залежно від ваших потреб, бо моє застосування було поганим.
    На Android 10 додаток виходить з ладу з повідомленням
    "Виклик startActivity () поза контекстом діяльності вимагає прапор FLAG_ACTIVITY_NEW_TASK. Це дійсно те, що ви хочете?" .
    Тому для роботи на Android 10 вам потрібно використовувати FALG_ACTIVITY_NEW_TASK, і ви не можете виконувати всі дії в одному завданні.
    Як ви бачите, поведінка відрізняється між версіями Android, дивно.

  • якщо запустити App2: SecondaryActivity з контекстом діяльності, все піде добре, і ви можете запустити всі дії в одній задачі, що призводить до лінійної навігації за заднім числом.

Я сподіваюся, що я додав корисну інформацію

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.