| 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> |
| --> |