579 lines
54 KiB
Plaintext
579 lines
54 KiB
Plaintext
page.title=Задачи и стек переходов назад
|
||
parent.title=Операции
|
||
parent.link=activities.html
|
||
@jd:body
|
||
|
||
<div id="qv-wrapper">
|
||
<div id="qv">
|
||
|
||
<h2>Содержание документа</h2>
|
||
<ol>
|
||
<li><a href="#ActivityState">Сохранение состояния операции</a></li></li>
|
||
<li><a href="#ManagingTasks">Управление задачами</a>
|
||
<ol>
|
||
<li><a href="#TaskLaunchModes">Определение режимов запуска</a></li>
|
||
<li><a href="#Affinities">Обработка привязок</a></li>
|
||
<li><a href="#Clearing">Очистка стека переходов назад</a></li>
|
||
<li><a href="#Starting">Запуск задачи</a></li>
|
||
</ol>
|
||
</li>
|
||
</ol>
|
||
|
||
<h2>Статьи</h2>
|
||
<ol>
|
||
<li><a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html">
|
||
Многозадачность в системе Android</a></li>
|
||
</ol>
|
||
|
||
<h2>См. также:</h2>
|
||
<ol>
|
||
<li><a href="{@docRoot}design/patterns/navigation.html">Дизайн Android:
|
||
навигация</a></li>
|
||
<li><a href="{@docRoot}guide/topics/manifest/activity-element.html">Элемент манифеста
|
||
{@code <activity>}</a></li>
|
||
<li><a href="{@docRoot}guide/components/recents.html">Экран обзора</a></li>
|
||
</ol>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<p>Обычно приложение содержит несколько <a href="{@docRoot}guide/components/activities.html">операций</a>. Каждая операция
|
||
должна разрабатываться в связи с действием определенного типа, которое пользователь может выполнять, и может запускать другие
|
||
операции. Например, приложение электронной почты может содержать одну операцию для отображения списка новых сообщений.
|
||
Когда пользователь выбирает сообщение, открывается новая операция для просмотра этого сообщения.</p>
|
||
|
||
<p>Операция может даже запускать операции, существующие в других приложениях на устройстве. Например,
|
||
если ваше приложение хочет отправить сообщение электронной почты, вы можете определить намерение для выполнения
|
||
действия «отправить» и включить в него некоторые данные, например, адрес электронной почты и текст сообщения. После этого открывается операция из другого
|
||
приложения, которая объявила, что она обрабатывает намерения такого типа. В этом случае намерение состоит в том, чтобы
|
||
отправить сообщение электронной почты, поэтому в приложении электронной почты запускается операция «составить сообщение» (если одно намерение
|
||
может обрабатываться несколькими операциями, система предлагает пользователю выбрать, какую из операций использовать). После отправки сообщения электронной почты
|
||
ваша операция возобновляет работу, и все выглядит так, будто операция отправки электронной почты является частью вашего приложения. Хотя
|
||
операции могут быть частями разных приложений, система Android поддерживает удобство работы
|
||
пользователя, сохраняя обе операции в одной <em>задаче</em>.</p>
|
||
|
||
<p>Задача — это коллекция операций, с которыми взаимодействует пользователь
|
||
при выполнении определенного задания. Операции упорядочены в виде стека (<em>стека переходов назад</em>), в том
|
||
порядке, в котором открывались операции.</p>
|
||
|
||
<!-- SAVE FOR WHEN THE FRAGMENT DOC IS ADDED
|
||
<div class="sidebox-wrapper">
|
||
<div class="sidebox">
|
||
<h3>Adding fragments to a task's back stack</h3>
|
||
|
||
<p>Your activity can also include {@link android.app.Fragment}s to the back stack. For example,
|
||
suppose you have a two-pane layout using fragments, one of which is a list view (fragment A) and the
|
||
other being a layout to display an item from the list (fragment B). When the user selects an item
|
||
from the list, fragment B is replaced by a new fragment (fragment C). In this case, it might be
|
||
desireable for the user to navigate back to reveal fragment B, using the <em>Back</em> button.</p>
|
||
<p>In order to add fragment B to the back stack so that this is possible, you must call {@link
|
||
android.app.FragmentTransaction#addToBackStack addToBackStack()} before you {@link
|
||
android.app.FragmentTransaction#commit()} the transaction that replaces fragment B with fragment
|
||
C.</p>
|
||
<p>For more information about using fragments and adding them to the back stack, see the {@link
|
||
android.app.Fragment} class documentation.</p>
|
||
|
||
</div>
|
||
</div>
|
||
-->
|
||
|
||
<p>Начальным местом для большинства задач является главный экран устройства. Когда пользователь касается значка в средстве
|
||
запуска
|
||
приложений (или ярлыка на главном экране), эта задача приложения переходит на передний план. Если для
|
||
приложения нет задач (приложение не использовалось в последнее время), тогда создается новая задача
|
||
и открывается «основная» операция для этого приложения в качестве корневой операции в стеке.</p>
|
||
|
||
<p>Когда текущая операция запускает другую, новая операция помещается в вершину стека
|
||
и получает фокус. Предыдущая операция остается в стеке, но ее выполнение останавливается. Когда операция останавливается
|
||
, система сохраняет текущее состояние ее пользовательского интерфейса. Когда пользователь нажимает кнопку
|
||
<em>Назад</em>,
|
||
текущая операция удаляется из вершины стека (операция уничтожается) и возобновляется
|
||
работа предыдущей операции (восстанавливается предыдущее состояние ее пользовательского интерфейса). Операции в стеке
|
||
никогда не переупорядочиваются, только добавляются в стек и удаляются из него — добавляются в стек при запуске текущей операцией
|
||
и удаляются, когда пользователь выходит из нее с помощью кнопки <em>Назад</em>. По существу,
|
||
стек
|
||
переходов назад работает по принципу «последним вошел — первым вышел». На рисунке 1 это поведение
|
||
показано на временной шкале: состояние операций и текущее состояние стека переходов назад
|
||
показано в каждый момент времени.</p>
|
||
|
||
<img src="{@docRoot}images/fundamentals/diagram_backstack.png" alt="" />
|
||
<p class="img-caption"><strong>Рисунок 1.</strong> Иллюстрация того, как каждая новая операция в задаче
|
||
добавляет элемент в стек переходов назад. Когда пользователь нажимает кнопку<em>Назад</em>, текущая
|
||
операция
|
||
уничтожается, и возобновляется работа предыдущей операции.</p>
|
||
|
||
|
||
<p>Если пользователь продолжает нажимать кнопку <em>Назад</em>, операции поочередно удаляются из стека,
|
||
открывая
|
||
предыдущую операцию, пока пользователь не вернется на главный экран (или в операцию, которая была запущена
|
||
в начале выполнения задачи). Когда все операции удалены из стека, задача прекращает существование.</p>
|
||
|
||
<div class="figure" style="width:287px">
|
||
<img src="{@docRoot}images/fundamentals/diagram_multitasking.png" alt="" /> <p
|
||
class="img-caption"><strong>Рисунок 2.</strong> Две задачи: Задача B взаимодействует с пользователем
|
||
на переднем плане, тогда как Задача A находится в фоновом режиме, ожидая возобновления.</p>
|
||
</div>
|
||
<div class="figure" style="width:215px">
|
||
<img src="{@docRoot}images/fundamentals/diagram_multiple_instances.png" alt="" /> <p
|
||
class="img-caption"><strong>Рисунок 3.</strong> Создается несколько экземпляров одной операции.</p>
|
||
</div>
|
||
|
||
<p>Задача — это связанный блок, который может переходить в фоновый режим, когда пользователи начинают новую задачу или переходят
|
||
на главный экран с помощью кнопки <em>Домой</em>. В фоновом режиме все операции
|
||
задачи
|
||
остановлены, но стек обратного вызова для задачи остается неизменным. Задача просто потеряла фокус во время
|
||
выполнения другой задачи, как показано на рисунке 2. Затем задача может вернуться на передний план, так что пользователи
|
||
могут продолжить ее с прерванного места. Предположим, например, что текущая задача (Задача A) содержит три операции
|
||
в своем стеке — две операции под текущей операцией. Пользователь нажимает кнопку <em>Домой</em>,
|
||
затем запускает
|
||
новое приложение из средства запуска приложений. Когда появляется главный экран, Задача A переходит
|
||
в фоновый режим. Когда запускается новое приложение, система запускает задачу для этого приложения
|
||
(Задачу B) со своим собственным стеком операций. После взаимодействия с этим
|
||
приложением пользователь снова возвращается на главный экран и выбирает изначально запущенную
|
||
Задачу A. Теперь Задача A переходит на передний
|
||
план — все три операции ее стека остались неизменными, и возобновляется операция, находящаяся на
|
||
вершине стека. В этот
|
||
момент пользователь может также переключиться обратно на Задачу B, перейдя на главный экран и выбрав значок приложения,
|
||
которое запустило эту задачу (или выбрав задачу приложения на
|
||
<a href="{@docRoot}guide/components/recents.html">экране обзора</a>).
|
||
Это пример многозадачности в системе Android.</p>
|
||
|
||
<p class="note"><strong>Примечание.</strong> В фоновом режиме может находиться несколько задач одновременно.
|
||
Однако, если пользователь запускает много фоновых задач одновременно, система может начать
|
||
уничтожение фоновых операций для освобождения памяти, что приведет к потере состояния задач.
|
||
См. следующий раздел <a href="#ActivityState">Состояние операции</a>.</p>
|
||
|
||
<p>Поскольку операции в стеке никогда не переупорядочиваются, если ваше приложение позволяет
|
||
пользователям запускать определенную операцию из нескольких операций, новый экземпляр
|
||
такой операции создается и помещается в стек (вместо помещения любого из предыдущих экземпляров
|
||
операции на вершину стека). По существу, для одной операции вашего приложения может быть создано несколько
|
||
экземпляров (даже из разных задач), как показано на рисунке 3. Поэтому, если пользователь переходит назад с помощью
|
||
кнопки <em>Назад</em>, каждый экземпляр операции появляется в том порядке, в котором они
|
||
были открыты (каждый
|
||
со своим состоянием пользовательского интерфейса). Однако вы можете изменить это поведение, если вы не хотите, чтобы создавалось несколько
|
||
экземпляров операции. Это описано в разделе <a href="#ManagingTasks">Управление задачами</a> ниже.</p>
|
||
|
||
|
||
<p>Подведем итоги поведения операций и задач:</p>
|
||
|
||
<ul>
|
||
<li>Когда Операция A запускает Операцию B, Операция A останавливается, но система сохраняет ее состояние
|
||
(например, положение прокрутки и текст, введенный в формы).
|
||
Если пользователь нажимает кнопку <em>Назад</em> в Операции B, Операция A возобновляет работу
|
||
из сохраненного состояния.</li>
|
||
<li>Когда пользователь выходит из задачи нажатием кнопки <em>Домой</em>, текущая операция
|
||
останавливается и
|
||
ее задача переводится в фоновый режим. Система сохраняет состояние каждой операции в задаче. Если
|
||
пользователь впоследствии возобновляет задачу, выбирая значок запуска задачи, она переводится
|
||
на передний план и возобновляет операцию на вершине стека.</li>
|
||
<li>Если пользователь нажимает кнопку <em>Назад</em>, текущая операция удаляется из стека
|
||
и
|
||
уничтожается. Возобновляется предыдущая операция в стеке. Когда операция уничтожается, система
|
||
<em>не</em> сохраняет состояние операции.</li>
|
||
<li>Можно создавать несколько экземпляров операции, даже из других задач.</li>
|
||
</ul>
|
||
|
||
|
||
<div class="note design">
|
||
<p><strong>Дизайн навигации</strong></p>
|
||
<p>Для получения дополнительной информации о работе навигации в приложении Android, прочитайте раздел <a href="{@docRoot}design/patterns/navigation.html">Навигация</a> руководства «Дизайн для Android».</p>
|
||
</div>
|
||
|
||
|
||
<h2 id="ActivityState">Сохранение состояния операции</h2>
|
||
|
||
<p>Как говорилось выше, система по умолчанию сохраняет состояние операции, когда она
|
||
останавливается. Таким образом, когда пользователи возвращаются обратно в предыдущую операцию, восстанавливается ее пользовательский интерфейс
|
||
в момент остановки. Однако вы можете — и <strong>должны</strong> — с упреждением сохранять
|
||
состояние ваших операций посредством методов обратного вызова на случай уничтожения операции и необходимости ее
|
||
повторного создания.</p>
|
||
|
||
<p>Когда система останавливает одну из ваших операций (например, когда запускается новая операция или задача
|
||
перемещается в фоновый режим), система может полностью уничтожить эту операцию, если необходимо восстановить
|
||
память системы. Когда это происходит, информация о состоянии операции теряется. Если это происходит,
|
||
система
|
||
знает, что операция находится в стеке переходов назад, но когда операция переходит
|
||
на вершину стека, система должна создать ее повторно (а не возобновить ее). Чтобы избежать
|
||
потери работы пользователя, вы должны с упреждением сохранять ее путем реализации методов
|
||
обратного вызова {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}
|
||
в вашей операции.</p>
|
||
|
||
<p>Дополнительную информацию о сохранении состояния вашей операции см. в документе
|
||
<a href="{@docRoot}guide/components/activities.html#SavingActivityState">Операции</a>.</p>
|
||
|
||
|
||
|
||
<h2 id="ManagingTasks">Управление задачами</h2>
|
||
|
||
<p>Для большинства приложений способ, которым Android управляет задачами и стеком переходов назад, описанный выше, — помещение всех
|
||
операций последовательно в одну задачу в стек «последним вошёл — первым вышел», —
|
||
работает хорошо, и вы не должны беспокоиться о связи ваших операций с задачами
|
||
или об их существовании в стеке переходов назад. Однако вы можете решить, что вы хотите прервать
|
||
обычное поведение. Возможно, вы хотите, чтобы операция в вашем приложении начинала новую задачу
|
||
при запуске (вместо помещения в текущую задачу), или при запуске операции вы хотите
|
||
перенести на передний план ее существующий экземпляр (вместо создания нового
|
||
экземпляра на вершине стека переходов назад), или вы хотите чтобы при выходе пользователя из задачи из вашего стек переходов удалялись все
|
||
операции, кроме корневой операции.</p>
|
||
|
||
<p>Вы можете совершать эти и многие другие действия с помощью атрибутов в элементе манифеста
|
||
<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>
|
||
и с помощью флагов в намерении, которое вы передаете в
|
||
{@link android.app.Activity#startActivity startActivity()}.</p>
|
||
|
||
<p>В этом смысле главными атрибутами <a href="{@docRoot}guide/topics/manifest/activity-element.html">
|
||
{@code <activity>}</a>, которые вы можете использовать, являются следующие:</p>
|
||
|
||
<ul class="nolist">
|
||
<li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">
|
||
{@code taskAffinity}</a></li>
|
||
<li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">
|
||
{@code launchMode}</a></li>
|
||
<li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">
|
||
{@code allowTaskReparenting}</a></li>
|
||
<li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">
|
||
{@code clearTaskOnLaunch}</a></li>
|
||
<li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always">
|
||
{@code alwaysRetainTaskState}</a></li>
|
||
<li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">
|
||
{@code finishOnTaskLaunch}</a></li>
|
||
</ul>
|
||
|
||
<p>А главными флагами намерений, которые вы можете использовать, являются следующие:</p>
|
||
|
||
<ul class="nolist">
|
||
<li>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</li>
|
||
<li>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</li>
|
||
<li>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</li>
|
||
</ul>
|
||
|
||
<p>В следующих разделах показано, как можно использовать эти атрибуты манифеста и флаги
|
||
намерений для определения связи операций с задачами и их поведения в стеке переходов назад.</p>
|
||
|
||
<p>Кроме того, отдельно обсуждаются рекомендации о представлении задач и операций и управлении ими
|
||
на экране обзора. Дополнительную информацию см. в разделе
|
||
<a href="{@docRoot}guide/components/recents.html">Экран обзора</a>. Обычно следует разрешить системе определить способ представления вашей задачи и
|
||
операций на экране обзора. Вам не нужно менять это поведение.</p>
|
||
|
||
<p class="caution"><strong>Внимание!</strong> В большинстве приложений не следует прерывать поведение
|
||
операций и задач по умолчанию. Если вы обнаружили, что вашей операции необходимо изменить
|
||
поведение по умолчанию, будьте внимательны и протестируйте удобство работы с операцией во время
|
||
запуска и при обратной навигации к ней из других операций и задач с помощью кнопки <em>Назад</em>.
|
||
Обязательно протестируйте поведение навигации, которое может противоречить поведению, ожидаемому пользователем.</p>
|
||
|
||
|
||
<h3 id="TaskLaunchModes">Определение режимов запуска</h3>
|
||
|
||
<p>Режимы запуска позволяют вам определять связь нового экземпляра операции
|
||
с текущей задачей. Вы можете задавать различные режимы запуска двумя способами:</p>
|
||
<ul class="nolist">
|
||
<li><a href="#ManifestForTasks">Использование файла манифеста</a>
|
||
<p>Когда вы объявляете операцию в вашем файле манифеста, вы можете указать, как операция
|
||
должна связываться с задачами при ее запуске.</li>
|
||
<li><a href="#IntentFlagsForTasks">Использование флагов намерений</a>
|
||
<p>Когда вы вызываете {@link android.app.Activity#startActivity startActivity()},
|
||
вы можете включить флаг в {@link android.content.Intent}, который объявляет, как должна быть связана
|
||
новая операция с текущей задачей (и должна ли).</p></li>
|
||
</ul>
|
||
|
||
<p>По существу, если Операция A запускает Операцию B, Операция B может определить в своем манифесте, как она
|
||
должна быть связана с текущей задачей (если вообще должна), а Операция A может также запросить, как Операция B
|
||
должна быть связана с текущей задачей. Если обе операции определяют, как Операция B
|
||
должна быть связана с задачей, тогда запрос Операции A (как определено в намерении) обрабатывается через
|
||
запрос Операции B (как определено в ее манифесте).</p>
|
||
|
||
<p class="note"><strong>Примечание.</strong> Некоторые режимы запуска, доступные для файла манифеста,
|
||
недоступны в виде флагов для намерения и, аналогичным образом, некоторые режимы запуска, доступные в виде флагов
|
||
для намерения, не могут быть определены в манифесте.</p>
|
||
|
||
|
||
<h4 id="ManifestForTasks">Использование файла манифеста</h4>
|
||
|
||
<p>При объявлении операции в вашем файле манифеста вы можете указать, как операция должна
|
||
быть связана с задачей посредством атрибута <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
|
||
launchMode}</a>
|
||
элемента <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>.</p>
|
||
|
||
<p>Атрибут <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
|
||
launchMode}</a> указывает инструкцию по запуску операции в
|
||
задаче. Существует четыре различных режима запуска,
|
||
которые вы можете назначить атрибуту
|
||
<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code>:</p>
|
||
|
||
<dl>
|
||
<dt>{@code "standard"} (режим по умолчанию)</dt>
|
||
<dd>Режим по умолчанию. Система создает новый экземпляр операции в задаче, из
|
||
которой она была запущена, и направляет ему намерение. Может быть создано несколько экземпляров операции,
|
||
каждый экземпляр может принадлежать различным задачам, и одна задача может содержать несколько экземпляров.</dd>
|
||
<dt>{@code "singleTop"}</dt>
|
||
<dd>Если экземпляр операции уже существует на вершине текущей задачи, система
|
||
направляет намерение в этот экземпляр путем вызова его метода {@link
|
||
android.app.Activity#onNewIntent onNewIntent()}, а не путем создания нового экземпляра
|
||
операции. Может быть создано несколько экземпляров операции, каждый экземпляр может
|
||
принадлежать различным задачам, и одна задача может содержать несколько экземпляров (но только если
|
||
операция на вершине стека переходов назад <em>не</em> является существующим экземпляром операции).
|
||
<p>Предположим, что стек переходов назад задачи состоит из корневой операции A с операциями B, C
|
||
и D на вершине (стек имеет вид A-B-C-D и D находится на вершине). Поступает намерение для операции типа D.
|
||
Если D имеет режим запуска {@code "standard"} по умолчанию, запускается новый экземпляр класса и
|
||
стек принимает вид A-B-C-D-D. Однако, если D имеет режим запуска {@code "singleTop"}, существующий экземпляр
|
||
D получает намерение через {@link
|
||
android.app.Activity#onNewIntent onNewIntent()}, так как этот экземпляр находится на вершине стека —
|
||
стек сохраняет вид A-B-C-D. Однако, если поступает намерение для операции типа B, тогда в стек
|
||
добавляется новый экземпляр B, даже если он имеет режим запуска {@code "singleTop"}.</p>
|
||
<p class="note"><strong>Примечание.</strong> Когда создается новый экземпляр операции,
|
||
пользователь может нажать кнопку <em>Назад</em> для возврата к предыдущей операции. Но когда существующий
|
||
экземпляр
|
||
операции обрабатывает новое намерение, пользователь не может нажать кнопку <em>Назад</em> для возврата к
|
||
состоянию
|
||
операции до поступления нового намерения в {@link android.app.Activity#onNewIntent
|
||
onNewIntent()}.</p>
|
||
</dd>
|
||
|
||
<dt>{@code "singleTask"}</dt>
|
||
<dd>Система создает новую задачу и создает экземпляр операции в корне новой задачи.
|
||
Однако, если экземпляр операции уже существует в отдельной задаче, система направляет
|
||
намерение в существующий экземпляр путем вызова его метода {@link
|
||
android.app.Activity#onNewIntent onNewIntent()}, а не путем создания нового экземпляра. Одновременно
|
||
может существовать только один экземпляр операции.
|
||
<p class="note"><strong>Примечание.</strong> Хотя операция запускает новую задачу, кнопка
|
||
<em>Назад</em> возвращает пользователя к предыдущей операции.</p></dd>
|
||
<dt>{@code "singleInstance"}.</dt>
|
||
<dd>То же, что и {@code "singleTask"}, но при этом система не запускает никаких других операций
|
||
в задаче, содержащей этот экземпляр. Операция всегда является единственным членом своей задачи;
|
||
любые операции, запущенные этой операцией, открываются в отдельной задаче.</dd>
|
||
</dl>
|
||
|
||
|
||
<p>В качестве другого примера: приложение Android Browser объявляет, что операция веб-браузера должна
|
||
всегда открываться в своей собственной задаче — путем указания режима запуска {@code singleTask} в элементе <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>.
|
||
Это означает, что если ваше приложение выдает
|
||
намерение открыть Android Browser, его операция <em>не</em> помещается в ту же
|
||
задачу, что и ваше приложение. Вместо этого, либо для браузера запускается новая задача, либо, если браузер уже
|
||
имеет задачу, работающую в фоновом режиме, эта задача переводится на передний план для обработки нового
|
||
намерения.</p>
|
||
|
||
<p>И при запуске операции в новой задаче, и при запуске операции в существующей задаче,
|
||
кнопка <em>Назад</em> всегда возвращает пользователя к предыдущей операции. Однако, если вы
|
||
запускаете операцию, которая указывает режим запуска {@code singleTask}, вся задача переводится на передний план, если экземпляр
|
||
этой операции существует в фоновой задаче. В этот момент
|
||
стек переходов назад помещает все операции из задачи, переведенной на передний план, на вершину
|
||
стека. Рисунок 4 иллюстрирует сценарий этого типа.</p>
|
||
|
||
<img src="{@docRoot}images/fundamentals/diagram_backstack_singletask_multiactivity.png" alt="" />
|
||
<p class="img-caption"><strong>Рисунок 4.</strong> Представление того, как операция с режимом
|
||
запуска singleTask добавляется в стек переходов назад. Если операция уже является частью
|
||
фоновой задачи со своим собственным стеком переходов назад, то весь стек переходов назад также переносится вверх,
|
||
на вершину текущей задачи.</p>
|
||
|
||
<p>Дополнительную информацию об использовании режимов запуска в файле манифеста см. в документации элемента
|
||
<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>,
|
||
где более подробно обсуждаются атрибут {@code launchMode}
|
||
и принимаемые значения.</p>
|
||
|
||
<p class="note"><strong>Примечание.</strong> Поведение, которое вы указываете для вашей операции с помощью атрибута <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a>,
|
||
может быть переопределено флагами, включенными в намерение, которое запускает вашу операцию, как описано
|
||
в следующем разделе.</p>
|
||
|
||
|
||
|
||
<h4 id="#IntentFlagsForTasks">Использование флагов намерений</h4>
|
||
|
||
<p>При запуске операции вы можете изменить связывание операции с ее задачей по умолчанию
|
||
путем включения флагов в намерение, которое доставляется в {@link
|
||
android.app.Activity#startActivity startActivity()}. Для изменения поведения по умолчанию
|
||
вы можете использовать следующие флаги:</p>
|
||
|
||
<p>
|
||
<dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt>
|
||
<dd>Запуск операции в новой задаче. Если задача уже работает для операции, которую вы запускаете
|
||
сейчас, эта задача переводится на передний план, ее последнее состояние восстанавливается, и операция получает
|
||
новое намерение в {@link android.app.Activity#onNewIntent onNewIntent()}.
|
||
<p>Это приводит к тому же поведению, что и значение <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> в режиме {@code "singleTask"},
|
||
как описано в предыдущем разделе.</p></dd>
|
||
<dt>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</dt>
|
||
<dd>Если запускаемая операция является текущей операцией (находится на вершине стека переходов назад), тогда
|
||
вызов в {@link android.app.Activity#onNewIntent onNewIntent()} получает существующий экземпляр,
|
||
без создания нового экземпляра операции.
|
||
<p>Это приводит к тому же поведению, что и значение <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> в режиме {@code "singleTop"},
|
||
как описано в предыдущем разделе.</p></dd>
|
||
<dt>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</dt>
|
||
<dd>Если запускаемая операция уже работает в текущей задаче, тогда вместо
|
||
запуска нового экземпляра этой операции уничтожаются все другие операции, расположенные в стеке выше нее
|
||
, и это намерение доставляется в возобновленный экземпляр этой операции (которая теперь находится на вершине стека)
|
||
посредством {@link android.app.Activity#onNewIntent onNewIntent()}).
|
||
<p>Для формирования такого поведения не существует значения для атрибута
|
||
<a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a>.</p>
|
||
<p>Флаг {@code FLAG_ACTIVITY_CLEAR_TOP} чаще всего используется совместно с
|
||
флагом {@code FLAG_ACTIVITY_NEW_TASK}.
|
||
При использовании вместе эти флаги позволяют найти существующую операцию
|
||
в другой задаче и поместить ее в положение, где она сможет реагировать на намерение. </p>
|
||
<p class="note"><strong>Примечание.</strong> Если для назначенной операции установлен режим запуска
|
||
{@code "standard"},
|
||
она также удаляется из стека и на ее месте запускается новый экземпляр, чтобы обработать
|
||
входящее намерение. Именно поэтому в режиме запуска {@code "standard"} всегда создается новый
|
||
экземпляр для нового намерения. </p>
|
||
</dd>
|
||
</dl>
|
||
|
||
|
||
|
||
|
||
|
||
<h3 id="Affinities">Обработка привязок</h3>
|
||
|
||
<p><em>Привязка</em> указывает предпочтительную принадлежность операции к задаче. По умолчанию все
|
||
операции из одного приложения имеют привязку друг к другу. Поэтому по умолчанию все
|
||
операции одного приложения предпочитают находиться в одной задаче. Однако вы можете изменить
|
||
привязку по умолчанию для операции. Операции, определенные
|
||
в разных приложениях, могут совместно использовать одну привязку; таким же образом операции, определенные в одном приложении, могут получить
|
||
привязки к разным задачам.</p>
|
||
|
||
<p>Вы можете изменить привязку любой данный операции с помощью
|
||
атрибута <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a>
|
||
элемента <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>.</p>
|
||
|
||
<p>Атрибут <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a>
|
||
принимает строковое значение, которое должно отличаться от имени пакета по умолчанию,
|
||
объявленного в элементе <a href="{@docRoot}guide/topics/manifest/manifest-element.html">
|
||
{@code <manifest>}
|
||
</a>, поскольку система использует это имя для идентификации привязки задачи по умолчанию
|
||
для приложения.</p>
|
||
|
||
<p>Привязка вступает в игру в двух случаях:</p>
|
||
<ul>
|
||
<li>Когда намерение, запускающее
|
||
операцию, содержит флаг
|
||
{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}.
|
||
|
||
<p>Новая операция по умолчанию запускается в задаче той операции,
|
||
которая вызвала {@link android.app.Activity#startActivity startActivity()}. Она помещается в тот же
|
||
стек переходов назад, что и вызывающая операция. Однако, если намерение, переданное
|
||
в {@link android.app.Activity#startActivity startActivity()},
|
||
содержит флаг {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK},
|
||
система ищет другую задачу для помещения новой операции. Часто это новая задача.
|
||
Но необязательно. Если уже существует задача с той же привязкой, что
|
||
и у новой операции, операция запускается в этой задаче. Если нет, операция начинает новую задачу.</p>
|
||
|
||
<p>Если этот флаг приводит к тому, что операция начинает новую задачу, и пользователь нажимает кнопку <em>Домой</em>
|
||
для выхода из нее,
|
||
должен существовать способ, позволяющий пользователю вернуться к задаче. Некоторые объекты (такие как
|
||
диспетчер уведомлений) всегда запускают операции во внешней задаче, а не в составе собственной, поэтому
|
||
они всегда помещают флаг {@code FLAG_ACTIVITY_NEW_TASK} в намерения, которые они передают
|
||
в {@link android.app.Activity#startActivity startActivity()}.
|
||
Если у вас есть операция, которую можно вызвать
|
||
внешним объектом, использующим этот флаг, позаботьтесь о том, чтобы у пользователя был независимый способ
|
||
вернуться в запущенную задачу, например, с помощью значка запуска (корневая операция задачи
|
||
содержит фильтр намерений {@link android.content.Intent#CATEGORY_LAUNCHER}; см. раздел <a href="#Starting">Запуск задачи</a> ниже).</p>
|
||
</li>
|
||
|
||
<li>Если для атрибута <a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">
|
||
{@code allowTaskReparenting}</a> операции установлено значение {@code "true"}.
|
||
<p>В этом случае операция может переместиться из запустившей ее задачи в задачу, к которой у операции есть привязка,
|
||
когда эта задача переходит на передний план.</p>
|
||
<p>Предположим, что операция, которая сообщает о погодных условиях в выбранных городах,
|
||
определена в составе приложения для путешественников. Она имеет ту же привязку, что и другие операции в том же
|
||
приложении (привязка приложения по умолчанию), и допускает переподчинение с этим атрибутом.
|
||
Когда одна из ваших операций запускает операцию прогноза погоды, она изначально принадлежит той же
|
||
задаче, что и ваша операция. Однако, когда задача из приложения для путешественников переходит на передний план,
|
||
операция прогноза погоды переназначается этой задаче и отображается внутри нее.</p>
|
||
</li>
|
||
</ul>
|
||
|
||
<p class="note"><strong>Совет.</strong> Если файл {@code .apk} содержит более одного «приложения»
|
||
с точки зрения пользователя, вы, вероятно, захотите использовать атрибут <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a>
|
||
для назначения разных привязок операциям, связанным с каждым «приложением».</p>
|
||
|
||
|
||
|
||
<h3 id="Clearing">Очистка стека переходов назад</h3>
|
||
|
||
<p>Если пользователь выходит из задачи на длительное время, система удаляет из задачи все операции, кроме
|
||
корневой операции. Когда пользователь возвращается в задачу, восстанавливается только корневая операция.
|
||
Система ведет себя таким образом, так как после продолжительного времени пользователи обычно уже забросили то,
|
||
чем они занимались ранее, и возвращаются в задачу, чтобы начать что-то новое. </p>
|
||
|
||
<p>Для изменения такого поведения предусмотрено несколько атрибутов операции, которыми вы можете воспользоваться: </p>
|
||
|
||
<dl>
|
||
<dt><code><a
|
||
href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code>
|
||
</dt>
|
||
<dd>Если для этого атрибута установлено значение {@code "true"} в корневой операции задачи,
|
||
описанное выше поведение по умолчанию не происходит.
|
||
Задача восстанавливает все операции в своем стеке даже по истечении длительного периода времени.</dd>
|
||
|
||
<dt><code><a
|
||
href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt>
|
||
<dd>Если для этого атрибута установлено значение {@code "true"} в корневой операции задачи,
|
||
стек очищается до корневой операции каждый раз, когда пользователь выходит из задачи
|
||
и возвращается в нее. Другими словами, этот атрибут противоположен атрибуту
|
||
<a href="{@docRoot}guide/topics/manifest/activity-element.html#always">
|
||
{@code alwaysRetainTaskState}</a>. Пользователь всегда возвращается в задачу в ее
|
||
исходном состоянии, даже после кратковременного выхода из нее.</dd>
|
||
|
||
<dt><code><a
|
||
href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code>
|
||
</dt>
|
||
<dd>Этот атрибут похож на <a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code clearTaskOnLaunch}</a>,
|
||
но он действует на
|
||
одну операцию, а не на всю задачу. Он также может приводить к удалению любой операции,
|
||
включая корневую операцию. Когда для него установлено значение {@code "true"},
|
||
операция остается частью задачи только для текущего сеанса. Если пользователь
|
||
выходит из задачи, а затем возвращается в нее, операция уже отсутствует.</dd>
|
||
</dl>
|
||
|
||
|
||
|
||
|
||
<h3 id="Starting">Запуск задачи</h3>
|
||
|
||
<p>Вы можете сделать операцию точкой входа, назначая ей фильтр намерений со значением
|
||
{@code "android.intent.action.MAIN"} в качестве указанного действия и
|
||
{@code "android.intent.category.LAUNCHER"}
|
||
в качестве указанной категории. Например:</p>
|
||
|
||
<pre>
|
||
<activity ... >
|
||
<intent-filter ... >
|
||
<action android:name="android.intent.action.MAIN" />
|
||
<category android:name="android.intent.category.LAUNCHER" />
|
||
</intent-filter>
|
||
...
|
||
</activity>
|
||
</pre>
|
||
|
||
<p>Фильтр намерений такого типа приводит к тому, что в средстве запуска приложения отображаются значок и метка для
|
||
операции, что позволяет пользователю запускать операцию
|
||
и возвращаться в создавшую ее задачу в любой момент после ее запуска.
|
||
</p>
|
||
|
||
<p>Эта вторая возможность очень важна: пользователи должны иметь возможность выходить из задачи и затем возвращаться в нее
|
||
с помощью этого средства запуска операции. Поэтому два <a href="#LaunchModes">режима
|
||
запуска</a>, которые отмечают, что операции всегда инициируют задачу, {@code "singleTask"} и
|
||
{@code "singleInstance"}, должны использоваться только в тех случаях, когда операция содержит
|
||
{@link android.content.Intent#ACTION_MAIN}
|
||
и фильтр {@link android.content.Intent#CATEGORY_LAUNCHER}. Представьте, например, что может произойти,
|
||
если фильтр отсутствует: намерение запускает операцию {@code "singleTask"}, которая инициирует
|
||
новую задачу, и пользователь некоторое время работает в этой задаче. Затем пользователь нажимает кнопку
|
||
<em>Домой</em>. Задача переводится в фоновый режим и не отображается. Теперь у пользователя нет возможности вернуться
|
||
к задаче, так как она отсутствует в средстве запуска приложения.</p>
|
||
|
||
<p>Для таких случаев, когда вы не хотите, чтобы пользователь мог вернуться к операции, установите для атрибута
|
||
<a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code finishOnTaskLaunch}</a>
|
||
элемента
|
||
<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>
|
||
значение {@code "true"} (см. раздел <a href="#Clearing">Очистка стека</a>).</p>
|
||
|
||
<p>Дополнительную информацию о представлении задач и операций и управлении ими
|
||
на экране обзора см. в разделе <a href="{@docRoot}guide/components/recents.html">
|
||
Экран обзора</a>.</p>
|
||
|
||
<!--
|
||
<h2>Beginner's Path</h2>
|
||
|
||
<p>For more information about how to use intents to
|
||
activate other application components and publish the intents to which your components
|
||
respond, continue with the <b><a
|
||
href="{@docRoot}guide/components/intents-filters.html">Intents and Intent
|
||
Filters</a></b> document.</p>
|
||
-->
|