diff options
Diffstat (limited to 'docs/html-intl/intl/ru/training/basics/activity-lifecycle')
5 files changed, 869 insertions, 0 deletions
diff --git a/docs/html-intl/intl/ru/training/basics/activity-lifecycle/index.jd b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/index.jd new file mode 100644 index 0000000..b8de11e --- /dev/null +++ b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/index.jd @@ -0,0 +1,72 @@ +page.title=Управление жизненным циклом операций +page.tags=жизненный цикл операций +helpoutsWidget=true + +trainingnavtop=true +startpage=true + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + + +<h2>Необходимые знания и компоненты</h2> +<ul> + <li>Как создать проект для Android (см. <a href="{@docRoot}training/basics/firstapp/creating-project.html">Создание проекта для Android +</a>)</li> +</ul> + + +<h2>См. также:</h2> +<ul> + <li><a href="{@docRoot}guide/components/activities.html">Операции</a></li> +</ul> + + +<h2>Попробуйте сами</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Загрузить демонстрацию</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + +</div> +</div> + +<p>Во время навигации пользователя по вашему приложению экземпляры +{@link android.app.Activity} внутри приложения переключаются между разными состояниями их +жизненного цикла Например, при первом запуске +операции она получает высокий приоритет в системе и привлекает внимание +пользователя. Во время этого процесса система Android вызывает серию методов жизненного цикла +операции, позволяя настроить пользовательский интерфейс и другие компоненты. Если пользователь выполняет +действие, запускающее другую операцию, или переключается на другое приложение, система вызывает другой набор +методов жизненного цикла для операции, поскольку она переносится на фоновый уровень (операция больше не +отображается, но экземпляр и состояние остаются без изменений).</p> + +<p>В методах обратного вызова жизненного цикла можно декларировать поведение операции, когда +пользователь прекращает и снова запускает операцию. Например, если вы разрабатываете проигрыватель потокового видео, +то можете сделать так, чтобы при переключении пользователя на другое приложение видео ставилось на паузу, +а сетевое соединение разрывалось. После возврата пользователя проигрыватель может снова подключиться к сети, и пользователь сможет возобновить воспроизведение +видео с того же самого места.</p> + +<p>В этом учебном курсе разъясняются важные методы обратного вызова жизненного цикла, которые получает каждый экземпляр {@link +android.app.Activity}, и описывается как их использовать, чтобы операция выполнялась так, как этого ожидает +пользователь, и не потребляла системные ресурсы, когда они ей не нужны.</p> + +<h2>Уроки</h2> + +<dl> + <dt><b><a href="starting.html">Запуск операции</a></b></dt> + <dd>Из этого урока вы узнаете об основах жизненного цикла операций, способах запуска вашего приложения пользователями и вариантах +создания базовых операций.</dd> + <dt><b><a href="pausing.html">Приостановка и возобновление операции</a></b></dt> + <dd>Вы узнаете, что происходит во время приостановки операции (окно операции частично затемнено) и возобновления операции, +и что следует делать во время подобных изменений состояния.</dd> + <dt><b><a href="stopping.html">Остановка и перезапуск операции</a></b></dt> + <dd>В этом уроке рассказывается о том, что происходит, когда пользователь полностью прекращает операцию, а потом возвращается к ней.</dd> + <dt><b><a href="recreating.html">Повторное создание операции</a></b></dt> + <dd>Вы узнаете, что происходит при полном прекращении операции, и как можно восстановить ее состояние +в случае необходимости.</dd> +</dl> + diff --git a/docs/html-intl/intl/ru/training/basics/activity-lifecycle/pausing.jd b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/pausing.jd new file mode 100644 index 0000000..c483780 --- /dev/null +++ b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/pausing.jd @@ -0,0 +1,147 @@ +page.title=Приостановка и возобновление операции +page.tags=жизненный цикл операции +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>Содержание этого урока</h2> + <ol> + <li><a href="#Pause">Приостановка операции</a></li> + <li><a href="#Resume">Возобновление операции</a></li> + </ol> + + <h2>См. также:</h2> + <ul> + <li><a href="{@docRoot}guide/components/activities.html">Операции</a> + </li> + </ul> + +<h2>Попробуйте сами</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Загрузить демонстрацию</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + + </div> +</div> + +<p>При обычном использовании приложения выполняемая на экране операция иногда закрывается другими +визуальными компонентами, в результате чего операция <em>приостанавливается</em>. Например, при открытии полупрозрачной +операции (например диалогового окна) предыдущая операция приостанавливается. Пока +операция остается частично видимой, но не остается в фокусе, она остается на паузе.</p> + +<p>Однако когда операция полностью закрывается и становится невидимой, она <em>останавливается</em> (об этом будет рассказано +на следующем уроке).</p> + +<p>Когда операция приостанавливается, система вызывает метод {@link +android.app.Activity#onPause onPause()} на {@link android.app.Activity}, что позволяет +остановить текущие действия, которые не должны продолжаться во время паузы (например воспроизведение видео), или сохранять +любую информацию, которая должна постоянно сохраняться в случае выхода пользователя из приложения. Если +пользователь возвращается к операции после паузы, система возобновляет ее и вызывает метод +{@link android.app.Activity#onResume onResume()}.</p> + +<p class="note"><strong>Примечание.</strong> Когда операция получает вызов {@link +android.app.Activity#onPause()}, это может указывать, что операция будет приостановлена совсем ненадолго +и пользователь сможет к ней вернуться. Однако обычно это является первым признаком +выхода пользователя из операции.</p> + +<img src="{@docRoot}images/training/basics/basic-lifecycle-paused.png" /> +<p class="img-caption"><strong>Рисунок 1</strong>. Когда полупрозрачная операция закрывает +вашу операцию, система вызывает {@link android.app.Activity#onPause onPause()} и операция +переходит в состояние паузы (1). Если пользователь возвращается к операции, находящейся в состоянии паузы, +система вызывает {@link android.app.Activity#onResume onResume()} (2).</p> + + +<h2 id="Pause">Приостановка операции</h2> + +<p>Когда система вызывает {@link android.app.Activity#onPause()} для операции, это +технически означает, что операция остается частично видимой. Однако чаще всего это означает, что +пользователь покидает операцию, и вскоре она войдет в состояние остановки. Обратный вызов + {@link android.app.Activity#onPause()} обычно следует использовать для следующих целей:</p> + +<ul> + <li>Остановка анимации или других текущих действий, которые могут потреблять ресурсы процессора.</li> + <li>Запись несохраненных изменений, если пользователи ожидают сохранения таких изменений +при выходе (например черновиков электронных писем).</li> + <li>Высвобождение ресурсов системы, например ресиверов, интерфейсов сенсоров (например +GPS) или других ресурсов, влияющих на время работы аккумулятора во время паузы и не +требующихся пользователю.</li> +</ul> + +<p>Например, если ваше приложение использует {@link android.hardware.Camera}, метод +{@link android.app.Activity#onPause()} подойдет для его освобождения.</p> + +<pre> +@Override +public void onPause() { + super.onPause(); // Always call the superclass method first + + // Release the Camera because we don't need it when paused + // and other activities might need to use it. + if (mCamera != null) { + mCamera.release() + mCamera = null; + } +} +</pre> + +<p>Обычно <strong>не</strong> следует использовать {@link android.app.Activity#onPause()} для сохранения +пользовательских изменений (например введенной в форму личной информации) в постоянном хранилище. Изменения +пользователя нужно сохранять в постоянном хранилище {@link android.app.Activity#onPause()} +только в тех случаях, когда пользователи ожидают автоматического сохранения изменений (например при составлении черновика электронного письма). +Однако в состоянии {@link +android.app.Activity#onPause()} следует избегать операций с высокой нагрузкой на процессор, например выполнения записи в базу данных, поскольку это может замедлить видимый +переход к следующей операции (вместо этого следует выполнять операции завершения работы с высокой нагрузкой при +{@link android.app.Activity#onStop onStop()}).</p> + +<p>Количество операций, выполняемых с помощью метода {@link android.app.Activity#onPause +onPause()}, должно быть не очень большим, чтобы пользователь мог быстро переключаться на следующую +задачу при фактической остановке вашей операции.</p> + +<p class="note"><strong>Примечание.</strong> При приостановке операции экземпляр {@link +android.app.Activity} остается в памяти и заново вызывается при возобновлении операции. +Не нужно заново инициализировать компоненты, созданные с использованием любого из методов обратного вызова для возобновления +операции.</p> + + + +<h2 id="Resume">Возобновление операции</h2> + +<p>Когда пользователь возобновляет операцию после паузы, система вызывает метод {@link +android.app.Activity#onResume()}.</p> + +<p>Учтите, что система вызывает этот метод каждый раз, когда ваша операция выполняется на экране, +в том числе и при первом ее запуске. В связи с этим, нужно реализовать метод {@link +android.app.Activity#onResume()} для инициализации компонентов, освобождаемых в состоянии {@link +android.app.Activity#onPause()}, и выполнения других операций инициализации, которые должны происходить каждый раз при возобновлении операции +(например при запуске анимированных элементов и компонентов, которые используются +только когда пользователь следит за операцией на экране).</p> + +<p>Следующий пример {@link android.app.Activity#onResume()} дополняет +пример {@link android.app.Activity#onPause()} выше. В нем инициализируется камера, +которая освобождается на время приостановки операции.</p> + +<pre> +@Override +public void onResume() { + super.onResume(); // Always call the superclass method first + + // Get the Camera instance as the activity achieves full user focus + if (mCamera == null) { + initializeCamera(); // Local method to handle camera init + } +} +</pre> + + + + + + + diff --git a/docs/html-intl/intl/ru/training/basics/activity-lifecycle/recreating.jd b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/recreating.jd new file mode 100644 index 0000000..acb89fa --- /dev/null +++ b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/recreating.jd @@ -0,0 +1,178 @@ +page.title=Воссоздание операции +page.tags=жизненный цикл операции +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>Содержание этого урока</h2> + <ol> + <li><a href="#SaveState">Сохранение состояния операции</a></li> + <li><a href="#RestoreState">Восстановление состояния операции</a></li> + </ol> + + <h2>См. также:</h2> + <ul> + <li><a href="{@docRoot}training/basics/supporting-devices/screens.html">Поддержка +различных экранов</a></li> + <li><a href="{@docRoot}guide/topics/resources/runtime-changes.html">Обработка изменений в режиме выполнения</a></li> + <li><a href="{@docRoot}guide/components/activities.html">Операции</a> + </li> + </ul> + + </div> +</div> + +<p>Существуют ситуации, когда операция уничтожается в результате нормального поведения приложения. Например, это происходит, +когда пользователь нажимает кнопку <em>Назад</em> или когда операция подает сигнал о своем уничтожении +посредством вызова {@link android.app.Activity#finish()}. Система также может уничтожить операцию, +если она остановлена и не используется в течение длительного времени, или если для выполнения операции на экране требуется больше +системных ресурсов и системе нужно закрыть фоновые процессы для освобождения памяти.</p> + +<p>Если операция уничтожается при нажатии пользователем кнопки <em>Назад</em> или завершении +операции, система считает, что экземпляр {@link android.app.Activity} исчезает навсегда, +так как такое поведение указывает, что операция больше не нужна. Однако если система уничтожает +операцию в связи с системными ограничениями (а не в процессе обычной работы приложения), хотя фактический +{@link android.app.Activity} экземпляр исчезает, система помнит о его существовании, и если +пользователь вернется к нему, система создаст новый экземпляр действия, используя набор +сохраненных данных, описывающий состояние операции на момент ее уничтожения. Сохраненные данные, используемые +системой для восстановления предыдущего состояния, называются "состоянием экземпляра" и представляют собой набор +пар "ключ-значение", хранящийся в объекте {@link android.os.Bundle}.</p> + +<p class="caution"><strong>Внимание!</strong> Ваша операция будет уничтожаться и восстанавливаться каждый раз, +когда пользователь вращает экран. При изменении ориентации экрана система уничтожает и заново создает +активную операцию, поскольку конфигурация экрана меняется и операции может потребоваться +загрузка альтернативных ресурсов (например нового макета).</p> + +<p>По умолчанию система использует состояние экземпляра {@link android.os.Bundle} для сохранения информации +о каждом объекте {@link android.view.View} в макете операции (например, о текстовом значении, +введенном в объект {@link android.widget.EditText}). Таким образом, если экземпляр вашей операции уничтожается и +воссоздается заново, происходит восстановление предыдущего состояния макета, +и при этом вам не нужно добавлять в приложение дополнительный код. Однако операция +может содержать больше информации о состоянии, чем вы хотите восстановить, например переменные, +отслеживающие ход выполнения операции пользователем.</p> + +<p class="note"><strong>Примечание.</strong> Чтобы система Android могла восстановить состояние +представлений операции, <strong>каждое представление должно иметь уникальный идентификатор</strong>, предоставляемый атрибутом +<a href="{@docRoot}reference/android/view/View.html#attr_android:id">{@code +android:id}</a>.</p> + +<p>Для сохранения дополнительных данных о состоянии операции, необходимо +заменить метод обратного вызова {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}. +Система вызывает этот метод, когда пользователь покидает операцию, +и передает ему объект {@link android.os.Bundle}, который будет сохранен в +случае, если операция будет неожиданно уничтожена. Если +системе нужно будет воссоздать экземпляр экземпляра операции, она передаст тот же объект {@link +android.os.Bundle} методам {@link android.app.Activity#onRestoreInstanceState +onRestoreInstanceState()} и {@link android.app.Activity#onCreate onCreate()}. +</p> + +<img src="{@docRoot}images/training/basics/basic-lifecycle-savestate.png" /> +<p class="img-caption"><strong>Рисунок 2</strong>. Когда система начинает останавливать операцию, она +вызывает {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} (1), чтобы вы могли указать +дополнительные данные состояния, которые нужно сохранить на случай необходимости воссоздания экземпляра {@link android.app.Activity}. +Если операция будет уничтожена, +и системе нужно будет воссоздать тот же экземпляр, она передаст данные +состояния, определенные в (1), методам {@link android.app.Activity#onCreate onCreate()} +(2) и {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} +(3).</p> + + + +<h2 id="SaveState">Сохранение состояния операции</h2> + +<p>Когда начинается остановка операции, система вызывает метод {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()}, чтобы операция могла сохранить информацию о состоянии с помощью набора пар +"ключ-значение". По умолчанию при реализации этого метода сохраняется информация о состоянии иерархии +представления операции, например текст в виджете {@link android.widget.EditText} или положение экрана +для {@link android.widget.ListView}.</p> + +<p>Для сохранения дополнительной информации о состоянии операции +необходимо реализовать {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} и добавить +к объекту {@link android.os.Bundle} пары "ключ-значение". Например:</p> + +<pre> +static final String STATE_SCORE = "playerScore"; +static final String STATE_LEVEL = "playerLevel"; +... + +@Override +public void onSaveInstanceState(Bundle savedInstanceState) { + // Save the user's current game state + savedInstanceState.putInt(STATE_SCORE, mCurrentScore); + savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel); + + // Always call the superclass so it can save the view hierarchy state + super.onSaveInstanceState(savedInstanceState); +} +</pre> + +<p class="caution"><strong>Внимание!</strong> Реализацию суперкласса {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} следует вызывать во всех случаях, чтобы реализация +по умолчанию могла сохранить состояние новой иерархии.</p> + + + +<h2 id="RestoreState">Восстановление состояния операции</h2> + +<p>В случае воссоздания операции после предыдущего уничтожения сохраненное +состояние можно восстановить из {@link android.os.Bundle}, куда система +передает данные операции. Методы обратного вызова {@link android.app.Activity#onCreate onCreate()} и {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} получают один и +тот же {@link android.os.Bundle}, содержащий информацию о состоянии экземпляра.</p> + +<p>Поскольку метод {@link android.app.Activity#onCreate onCreate()} вызывается, если +система создает новый экземпляр операции или восстанавливает предыдущий экземпляр, перед попыткой чтения необходимо убедиться, +что {@link android.os.Bundle} имеет состояние null. В этом случае +система создает новый экземпляр операции +вместо восстановления ранее уничтоженного экземпляра.</p> + +<p>Приведем пример восстановления некоторых данных о состоянии в {@link android.app.Activity#onCreate +onCreate()}:</p> + +<pre> +@Override +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); // Always call the superclass first + + // Check whether we're recreating a previously destroyed instance + if (savedInstanceState != null) { + // Restore value of members from saved state + mCurrentScore = savedInstanceState.getInt(STATE_SCORE); + mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); + } else { + // Probably initialize members with default values for a new instance + } + ... +} +</pre> + +<p>Вместо восстановления состояния в {@link android.app.Activity#onCreate onCreate()} вы +можете реализовать метод {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}, который система вызывает +после метода {@link android.app.Activity#onStart()}. Система вызывает {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} только при наличии сохраненного состояния +для восстановления, и поэтому вам не нужно проверять, имеет ли {@link android.os.Bundle} значение null:</p> + +<pre> +public void onRestoreInstanceState(Bundle savedInstanceState) { + // Always call the superclass so it can restore the view hierarchy + super.onRestoreInstanceState(savedInstanceState); + + // Restore state members from saved instance + mCurrentScore = savedInstanceState.getInt(STATE_SCORE); + mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); +} +</pre> + +<p class="caution"><strong>Внимание!</strong> Реализацию суперкласса {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} следует вызывать во всех случаях, чтобы реализация +по умолчанию могла сохранить состояние новой иерархии.</p> + +<p>Более подробную информацию о воссоздании операции в связи +с перезапуском во время исполнения (например при повороте экрана) можно найти в разделе <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Обработка изменений в режиме выполнения</a>.</p> + diff --git a/docs/html-intl/intl/ru/training/basics/activity-lifecycle/starting.jd b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/starting.jd new file mode 100644 index 0000000..3a946e2 --- /dev/null +++ b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/starting.jd @@ -0,0 +1,285 @@ +page.title=Запуск операции +page.tags=жизненный цикл операции +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>Содержание этого урока</h2> +<ol> + <li><a href="#lifecycle-states">Изучение обратных вызовов жизненного цикла</a></li> + <li><a href="#launching-activity">Указание операции, запускающей приложение</a></li> + <li><a href="#Create">Создание нового экземпляра</a></li> + <li><a href="#Destroy">Уничтожение операции</a></li> +</ol> + + <h2>См. также:</h2> + <ul> + <li><a href="{@docRoot}guide/components/activities.html">Операции</a></li> + </ul> + +<h2>Попробуйте сами</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Загрузить демонстрацию</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + + </div> +</div> + +<p>В отличие от других парадигм программирования, где приложения запускаются с использованием метода {@code main()}, система +Android запускает код в {@link android.app.Activity}экземпляре посредством активации определенных +методов обратного вызова, соответствующих определенным этапам его +жизненного цикла. Существует последовательность методов обратного вызова, которые запускают операцию и последовательность +методов обратного вызова, уничтожающих операцию.</p> + +<p>В этом уроке рассматриваются наиболее важные методы жизненного цикла и демонстрируется, как +обработать первый обратный вызов жизненного цикла, создающий новый экземпляр операции.</p> + + + +<h2 id="lifecycle-states">Изучение обратных вызовов жизненного цикла</h2> + +<p>В течение цикла существования операции система вызывает базовый набор методов жизненного цикла в +последовательности, сходной с многоступенчатой пирамидой. Таким образом, каждый этап +жизненного цикла операции представляет собой отдельную ступень пирамиды. Когда система создает новый экземпляр операции, +каждый метод обратного вызова перемещает состояние действия на одну ступень вверх. Вершина пирамиды представляет собой +точку, в которой операция выполняется в экранном режиме, и пользователь может с ней взаимодействовать.</p> + +<p>Когда пользователь начинает выходить из операции, система вызывает другие методы, которые перемещают состояние +операции вниз по пирамиде для уничтожения действия. В некоторых случаях действие +перемещает операцию вниз по пирамиде только частично и ждет (например когда пользователь переключается на другое приложение), +а затем операция может быть перемещена обратно вверх (если пользователь вернется к операции) и +возобновлена там, где пользователь вышел из нее.</p> + + +<img src="{@docRoot}images/training/basics/basic-lifecycle.png" /> +<p class="img-caption"><strong>Рисунок 1</strong>. Упрощенная иллюстрация жизненного цикла операции +в виде многоступенчатой пирамиды. На рисунке показано, что для каждого обратного вызова, +поднимающего операцию на одну ступень к состоянию возобновления на вершине пирамиды, +существует обратный вызов, опускающий операцию на одну ступень вниз. Возобновление операции также может производиться из состояний +паузы и остановки.</p> + + +<p>В зависимости от сложности операции, некоторые +методы жизненного цикла могут не требоваться. Однако очень важно понимать все методы и реализовать их так, чтобы +приложение работало так, как этого ожидают пользователи. Правильная реализация методов жизненного цикла операции +обеспечивает нормальную работу приложения в нескольких аспектах, в том числе:</p> +<ul> + <li>Не прекращает работу, если пользователь получает телефонный звонок или переключается на другое приложение +во время использования вашего приложения.</li> + <li>Не потребляет ценные системные ресурсы, когда пользователь не использует +его активно.</li> + <li>Сохраняет состояние приложения, если пользователь выходит из него и возвращается +позднее.</li> + <li>Не закрывается с ошибкой и не теряет данные пользователя при повороте экрана (смене ориентации между книжной +и альбомной.</li> +</ul> + +<!-- +<p class="table-caption"><strong>Table 1.</strong> Activity lifecycle state pairs and callback +methods.</p> +<table> + <tr> + <th scope="col">Lifecycle State</th> + <th scope="col">Startup Method</th> + <th scope="col">Teardown Method</th> + </tr> + <tr> + <td>Created / Destroyed</td> + <td>{@link android.app.Activity#onCreate onCreate()}</td> + <td>{@link android.app.Activity#onDestroy()}</td> + </tr> + <tr> + <td>Started / Stopped</td> + <td>{@link android.app.Activity#onStart()}</td> + <td>{@link android.app.Activity#onStop()}</td> + </tr> + <tr> + <td>Resumed / Resumed</td> + <td>{@link android.app.Activity#onResume()}</td> + <td>{@link android.app.Activity#onPause()}</td> + </tr> +</table> +--> + +<p>Как вы узнаете на следующих уроках, в некоторых ситуациях операция +переключается между разными состояниями, как показано на рисунке 1. Однако только три +из этих состояний могут быть статичными. Это означает, что операция может существовать относительно длительное +время только в одном из этих трех состояний.</p> +<dl> + <dt>Возобновление</dt> + <dd>В этом состоянии операция выполняется в экранном режиме, и пользователь может с ней взаимодействовать. +Иногда это состояние также называется рабочим состоянием.</dd> + <dt>Приостановка</dt> + <dd>В этом состоянии операция частично закрывается другой операцией — в экранном режиме +эта другая операция или является полупрозрачной, или не закрывает экран целиком. Приостановленная операция +не получает команд пользователя и не может выполнять код. + <dt>Остановка</dt> + <dd>В этом состоянии операция полностью скрыта и невидима для пользователя. Она считается находящейся в +фоновом режиме. В состоянии остановки сохраняется экземпляр операции и вся его информация +о состоянии, например, переменных, однако операция не может выполнять код.</dd> +</dl> + +<p>Другие состояния (создание и запуск) являются переходными, и система быстро переходит от них +к следующим состояниям посредством вызова следующего метода обратного вызова в жизненном цикле. Таким образом, после вызова +{@link android.app.Activity#onCreate onCreate()} система быстро вызывает {@link +android.app.Activity#onStart()}, а затем сразу же вызывает {@link +android.app.Activity#onResume()}.</p> + +<p>Так выглядит базовый жизненный цикл операции. Теперь рассмотрим определенные виды +поведения в жизненном цикле.</p> + + + +<h2 id="launching-activity">Указание операции, запускающей приложение</h2> + +<p>Когда пользователь выбирает значок приложения на главном экране, система вызывает метод {@link +android.app.Activity#onCreate onCreate()} для {@link android.app.Activity} в вашем приложении +в соответствии с тем, какую операцию вы задекларировали как операцию запуска (или основную операцию). Эта операция выступает +основной точкой входа в пользовательский интерфейс вашего приложения.</p> + +<p>Для определения основной операции вы можете использовать файл манифеста Android <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">{@code AndroidManifest.xml}</a>, +который находится в корневом каталоге вашего проекта.</p> + +<p>Основная операция приложения должна декларироваться в манифесте с помощью фильтра <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a>, включающего действие {@link +android.content.Intent#ACTION_MAIN MAIN} и категорию +{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER}. Например:</p> + +<pre> +<activity android:name=".MainActivity" android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> +</activity> +</pre> + +<p class="note"><strong>Примечание.</strong> При создании нового проекта Android с помощью инструментов +Android SDK файлы проекта по умолчанию включают класс {@link android.app.Activity}, который декларируется в +манифесте с помощью этого фильтра.</p> + +<p>Если для одной из операций не декларировано действие {@link android.content.Intent#ACTION_MAIN MAIN} или категория +{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER}, значок +приложения не будет отображатья в списке приложений на главном экране.</p> + + + +<h2 id="Create">Создание нового экземпляра</h2> + +<p>Большинство приложений содержат различные операции, позволяющие пользователю выполнять различные действия. +Как для основных операций, создаваемых при нажатии на значок приложения, так +и для других операций, которыми приложение реагирует на действия пользователя, система создает +каждый новый экземпляр {@link android.app.Activity} посредством вызова его метода {@link +android.app.Activity#onCreate onCreate()}.</p> + +<p>Вы должны реализовать метод {@link android.app.Activity#onCreate onCreate()} для выполнения базовой +логики запуска приложения, которое должно производиться только один раз для всего срока существования операции. Например, +ваша реализация {@link android.app.Activity#onCreate onCreate()} должна содержать определение пользовательского +интерфейса и возможно создавать экземпляры некоторых переменных уровня класса.</p> + +<p>Например, в следующем примере метода {@link android.app.Activity#onCreate onCreate()} +показан код, выполняющий фундаментальную настройку операции, включая +декларирование пользовательского интерфейса (определен в файле макета XML), определение составных переменных +и частичную настройку пользовательского интерфейса.</p> + +<pre> +TextView mTextView; // Member variable for text view in the layout + +@Override +public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Set the user interface layout for this Activity + // The layout file is defined in the project res/layout/main_activity.xml file + setContentView(R.layout.main_activity); + + // Initialize member TextView so we can manipulate it later + mTextView = (TextView) findViewById(R.id.text_message); + + // Make sure we're running on Honeycomb or higher to use ActionBar APIs + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + // For the main activity, make sure the app icon in the action bar + // does not behave as a button + ActionBar actionBar = getActionBar(); + actionBar.setHomeButtonEnabled(false); + } +} +</pre> + +<p class="caution"><strong>Внимание!</strong> Использование {@link android.os.Build.VERSION#SDK_INT} для +предотвращения запуска новых API-интерфейсов на старых системах поддерживается только в Android версии 2.0 (API-интерфейсы уровня +5) и более поздних версиях. В старых версиях возникнет ошибка времени исполнения.</p> + +<p>После завершения выполнения {@link android.app.Activity#onCreate onCreate()} система +быстро вызывает методы {@link android.app.Activity#onStart()} и {@link android.app.Activity#onResume()} по +очереди. Операция никогда не остается в состоянии создания или запуска. Технически +операция становится видимой для пользователя при вызове {@link android.app.Activity#onStart()}, однако затем сразу же происходит +{@link android.app.Activity#onResume()} и операция остается в состоянии возобновления, +пока что-то не произойдет, например пока не поступит телефонный звонок, пользователь не переключится +на другую операцию или экран устройства не выключится.</p> + +<p>На последующих уроках вы увидите, как можно с пользой использовать другие методы запуска, {@link +android.app.Activity#onStart()} и {@link android.app.Activity#onResume()}, в жизненном цикле операции +при возобновлении работы после паузы или остановки.</p> + +<p class="note"><strong>Примечание.</strong> Метод {@link android.app.Activity#onCreate onCreate()} +включает параметр <code>savedInstanceState</code>, о котором будет рассказано на +уроке <a href="recreating.html">Воссоздание операции</a>.</p> + + +<img src="{@docRoot}images/training/basics/basic-lifecycle-create.png" /> +<p class="img-caption"><strong>Рисунок 2.</strong> Еще один пример структуры жизненного +цикла операции, где основное внимание трем главным обратным вызовам, которые система выполняет по очереди при создании +нового экземпляра операции: {@link android.app.Activity#onCreate onCreate()}, {@link +android.app.Activity#onStart()} и {@link android.app.Activity#onResume()}. После завершения этой серии +обратных вызовов операция переходит в состояние возобновления, где пользователи могут +взаимодействовать с операцией до тех пор, пока не переключатся на другую операцию.</p> + + + + + + + +<h2 id="Destroy">Уничтожение операции</h2> + +<p>Первым обратным вызовом жизненного цикла операции является {@link android.app.Activity#onCreate +onCreate()}, а последним – {@link android.app.Activity#onDestroy}. Система вызывает +этот метод для операции, подавая окончательный сигнал +о том, что экземпляр операции полностью удаляется из системной памяти.</p> + +<p>Большинству приложений не требуется реализация этого метода, потому что ссылки локальных классов уничтожаются +вместе с операцией, а основные задачи по освобождению ресурсов операция выполняет в состояниях {@link +android.app.Activity#onPause} и {@link android.app.Activity#onStop}. Однако если ваша +операция содержит фоновые потоки, созданные во время выполнения {@link +android.app.Activity#onCreate onCreate()}, или в течение длительного времени использует другие ресурсы, могущие +вызывать утечку памяти при неправильном закрытии, их нужно уничтожить с помощью метода {@link +android.app.Activity#onDestroy}.</p> + +<pre> +@Override +public void onDestroy() { + super.onDestroy(); // Always call the superclass + + // Stop method tracing that the activity started during onCreate() + android.os.Debug.stopMethodTracing(); +} +</pre> + +<p class="note"><strong>Примечание.</strong> Система вызывает {@link android.app.Activity#onDestroy} +после вызова {@link android.app.Activity#onPause} и {@link +android.app.Activity#onStop} во всех случаях, кроме ситуации, когда вы вызываете {@link +android.app.Activity#finish()} из метода {@link android.app.Activity#onCreate onCreate()} +. В некоторых случаях, например когда ваша операция временно отвечает за принятие решения о запуске +другой операции, вы можете вызвать {@link android.app.Activity#finish()} из метода {@link +android.app.Activity#onCreate onCreate()} для уничтожения операции. В этом случае система +сразу же вызывает {@link android.app.Activity#onDestroy}, не вызывая другие методы жизненного +цикла.</p> diff --git a/docs/html-intl/intl/ru/training/basics/activity-lifecycle/stopping.jd b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/stopping.jd new file mode 100644 index 0000000..27c771f --- /dev/null +++ b/docs/html-intl/intl/ru/training/basics/activity-lifecycle/stopping.jd @@ -0,0 +1,187 @@ +page.title=Остановка и перезапуск операции +page.tags=жизненный цикл операции +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>Содержание этого урока</h2> + <ol> + <li><a href="#Stop">Остановка операции</a></li> + <li><a href="#Start">Запуск/перезапуск операции</a></li> + </ol> + + <h2>См. также:</h2> + <ul> + <li><a href="{@docRoot}guide/components/activities.html">Операции</a> + </li> + </ul> + +<h2>Попробуйте сами</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">Загрузить демонстрацию</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + + </div> +</div> + +<p>Правильное выполнение остановки и перезапуска операции является важным шагом в жизненном +цикле операции, благодаря которому пользователи понимают, что приложение не потеряет их данные. +Ниже приведен пример нескольких основных ситуаций с остановкой и перезапуском операции.</p> + +<ul> + <li>Пользователь открывает окно "Последние приложения" и переключается из вашего приложения в другое приложение. +При этом останавливается операция вашего приложения, работающего на экране. Если пользователь возвращается в ваше +приложение, нажав значок запуска на главном экране или через окно "Последние приложения", данная операция возобновляется.</li> + <li>Пользователь выполняет в вашем приложении действие, запускающее новую операцию. Текущая операция +останавливается при создании второй операции. Если после этого пользователь нажимает кнопку <em>Назад</em> +, первая операция запускается заново.</li> + <li>Пользователь получает телефонный звонок или переключается на другое приложение во время использования вашего приложения на своем телефоне.</li> +</ul> + +<p>Класс {@link android.app.Activity} предоставляет два метода жизненного цикла, {@link +android.app.Activity#onStop()} и {@link android.app.Activity#onRestart()}, позволяющие явно +обрабатывать остановку и перезапуск операции. В отличие от состояния паузы, +означающем частичное уничтожение пользовательского интерфейса, в состоянии остановки пользовательский интерфейс больше не +отображается и пользователь переключается на отдельную операцию (или отдельное приложение).</p> + +<p class="note"><strong>Примечание.</strong> Поскольку система хранит ваш экземпляр {@link android.app.Activity} +в системной памяти при остановке, вам, возможно, вообще не потребуется реализация методов +{@link android.app.Activity#onStop()} и {@link android.app.Activity#onRestart()} (или даже {@link +android.app.Activity#onStart()}. Большинство операций относительно простые, и операция +остановится и перезапустится нормально, вам только может потребоваться {@link +android.app.Activity#onPause()} для приостановки текущих операций и отключения от системных ресурсов.</p> + +<img src="{@docRoot}images/training/basics/basic-lifecycle-stopped.png" /> +<p class="img-caption"><strong>Рисунок 1.</strong> Когда пользователь выйдет из операции, система +вызовет {@link android.app.Activity#onStop onStop()} для остановки операции (1). Если пользователь возвращается +при остановке операции, система вызывает {@link android.app.Activity#onRestart onRestart()} +(2), затем сразу же {@link android.app.Activity#onStart onStart()} (3) и {@link +android.app.Activity#onResume()} (4). Вне зависимости от причины остановки +операции, система всегда вызывает {@link android.app.Activity#onPause onPause()} перед вызовом {@link +android.app.Activity#onStop onStop()}.</p> + + + +<h2 id="Stop">Остановка операции</h2> + +<p>Когда операция получает вызов метода {@link android.app.Activity#onStop()}, +она становится невидимой и освобождает практически все ресурсы, которые не нужны ей, когда пользователь ее не +использует. После остановки операции система может уничтожить экземпляр, если ей потребуется +освободить системную память. В чрезвычайных ситуациях система может закрыть процесс приложения без +вызова последнего метода обратного вызова {@link android.app.Activity#onDestroy()} операции, и поэтому важно +использовать {@link android.app.Activity#onStop()} для высвобождения ресурсов, которые могут вызвать утечку памяти.</p> + +<p>Хотя метод {@link android.app.Activity#onPause onPause()} вызывается до +{@link android.app.Activity#onStop()}, вам следует использовать {@link android.app.Activity#onStop onStop()} +для выполнения более масштабных операций выключения с использованием процессорных ресурсов, например при записи информации в базу +данных.</p> + +<p>В качестве примера приведем реализацию {@link android.app.Activity#onStop onStop()}, +сохраняющую содержание черновой заметки в постоянное хранилище:</p> + +<!-- TODO: Find a better example for onStop, because this kind of thing should probably use a +separate thread but that's too complicated to show here. --> +<pre> +@Override +protected void onStop() { + super.onStop(); // Always call the superclass method first + + // Save the note's current draft, because the activity is stopping + // and we want to be sure the current note progress isn't lost. + ContentValues values = new ContentValues(); + values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText()); + values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle()); + + getContentResolver().update( + mUri, // The URI for the note to update. + values, // The map of column names and new values to apply to them. + null, // No SELECT criteria are used. + null // No WHERE columns are used. + ); +} +</pre> + +<p>При остановке операции объект {@link android.app.Activity} остается в памяти +и вызывается повторно при возобновлении операции. Не нужно заново инициализировать компоненты, +созданные с использованием любого из методов обратного вызова для возобновления операции. Система также +отслеживает текущее состояние каждого {@link android.view.View} в макете, и если +пользователь вводит текст в виджет {@link android.widget.EditText}, этот текст сохраняется, так что его не +нужно специально сохранять и восстанавливать.</p> + +<p class="note"><strong>Примечание.</strong> Даже если система уничтожит операцию в период остановки, +она сохранит состояние объектов {@link android.view.View} (например, текста в {@link +android.widget.EditText}) в {@link android.os.Bundle} (наборе пар "ключ-значение") и восстановит +их, если пользователь вернется в тот же экземпляр операции (на <a href="recreating.html">следующем уроке</a> мы более подробно поговорим об использовании {@link android.os.Bundle} для сохранения +других данных состояния в случае уничтожения и воссоздания вашей операции).</p> + + + +<h2 id="Start">Запуск/перезапуск операции</h2> + +<p>Когда ваша операция возвращается в экранный режим из состояния остановки, она получает вызов +{@link android.app.Activity#onRestart()}. Система также вызывает метод {@link +android.app.Activity#onStart()}, что происходит каждый раз, когда операция становится видимой +(при перезапуске или первоначальном создании). Однако метод {@link +android.app.Activity#onRestart()} вызывается только при возобновлении операции из состояния +остановки, так что его можно использовать для выполнения специальных задач восстановления, которые могут требоваться только если операция +была остановлена, но не была уничтожена.</p> + +<p>Приложениям редко требуется использовать {@link android.app.Activity#onRestart()} для восстановления +состояния операции, и поэтому для этого метода нет правил, относящихся +к обычным приложениям. Однако поскольку ваш метод {@link android.app.Activity#onStop()} +должен фактически освободить все ресурсы операции, их нужно снова выделить +при перезапуске операции. Однако их также нужно выделять при первом +создании операции (когда нет существующего экземпляра операции). По этому причине обычно +используют метод обратного вызова {@link android.app.Activity#onStart()} в дополнение +к методу {@link android.app.Activity#onStop()}, поскольку система вызывает {@link +android.app.Activity#onStart()} как при создании операции, так и при ее перезапуске +после остановки.</p> + +<p>Например, если пользователь долго не пользовался приложением, +а затем вернулся в него, метод {@link android.app.Activity#onStart()} хорошо помогает убедиться, что требуемые +системные функции включены:</p> + +<pre> +@Override +protected void onStart() { + super.onStart(); // Always call the superclass method first + + // The activity is either being restarted or started for the first time + // so this is where we should make sure that GPS is enabled + LocationManager locationManager = + (LocationManager) getSystemService(Context.LOCATION_SERVICE); + boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + + if (!gpsEnabled) { + // Create a dialog here that requests the user to enable GPS, and use an intent + // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action + // to take the user to the Settings screen to enable GPS when they click "OK" + } +} + +@Override +protected void onRestart() { + super.onRestart(); // Always call the superclass method first + + // Activity being restarted from stopped state +} +</pre> + + + + +<p>Когда система уничтожает вашу операцию, она вызывает метод {@link android.app.Activity#onDestroy()} +для вашего {@link android.app.Activity}. Поскольку вы уже освобождаете большую часть +ресурсов с помощью {@link android.app.Activity#onStop()} к моменту вызова {@link +android.app.Activity#onDestroy()}, большинству приложений почти ничего не нужно делать. Этот метод представляет собой последний +шанс освободить ресурсы, могущие привести к утечке памяти, обеспечивая уверенность +в уничтожении дополнительных потоков и других долгосрочных действий, например, отслеживания +методов.</p> + |