diff options
author | Trevor Johns <trevorjohns@google.com> | 2016-04-05 19:43:35 -0700 |
---|---|---|
committer | Trevor Johns <trevorjohns@google.com> | 2016-04-05 20:32:07 -0700 |
commit | a5060ee80dbb48bd7fc545d2aeeeb657b79893ea (patch) | |
tree | 842bb82e198dccade4bfb3ceafcc01f96083cd34 /docs/html-intl/intl/ru/guide/components/activities.jd | |
parent | ebf3261aa6d80ad4ca1df0fd0509961ff7a1914e (diff) | |
parent | 9577d31b10aa654d3ba63947e7733945a358395e (diff) |
Merge branch 'mnc-mr-docs' into mnc-ub-dev
Large merge to reconnect automerger for docs branch to mainline.
Conflicts:
docs/html-intl/intl/es/index.jd
docs/html-intl/intl/es/preview/download.jd
docs/html-intl/intl/es/preview/index.jd
docs/html-intl/intl/ja/index.jd
docs/html-intl/intl/ja/preview/download.jd
docs/html-intl/intl/ja/preview/index.jd
docs/html-intl/intl/ko/index.jd
docs/html-intl/intl/ko/preview/download.jd
docs/html-intl/intl/ko/preview/index.jd
docs/html-intl/intl/pt-br/index.jd
docs/html-intl/intl/pt-br/preview/download.jd
docs/html-intl/intl/pt-br/preview/index.jd
docs/html-intl/intl/ru/index.jd
docs/html-intl/intl/ru/preview/download.jd
docs/html-intl/intl/ru/preview/index.jd
docs/html-intl/intl/zh-cn/index.jd
docs/html-intl/intl/zh-cn/preview/download.jd
docs/html-intl/intl/zh-cn/preview/index.jd
docs/html-intl/intl/zh-tw/index.jd
docs/html-intl/intl/zh-tw/preview/download.jd
docs/html-intl/intl/zh-tw/preview/index.jd
docs/html/guide/topics/manifest/compatible-screens-element.jd
docs/html/guide/topics/manifest/uses-feature-element.jd
docs/html/preview/download.jd
docs/html/preview/features/runtime-permissions.jd
docs/html/sdk/index.jd
docs/html/tools/revisions/studio.jd
docs/html/tools/sdk/eclipse-adt.jd
docs/html/tools/support-library/features.jd
telephony/java/android/telephony/TelephonyManager.java
Bug: 28000173
Change-Id: Iacab0481175f1b32e0ac3bab98cde9e994100e94
Diffstat (limited to 'docs/html-intl/intl/ru/guide/components/activities.jd')
-rw-r--r-- | docs/html-intl/intl/ru/guide/components/activities.jd | 756 |
1 files changed, 756 insertions, 0 deletions
diff --git a/docs/html-intl/intl/ru/guide/components/activities.jd b/docs/html-intl/intl/ru/guide/components/activities.jd new file mode 100644 index 000000000000..5f55a3521350 --- /dev/null +++ b/docs/html-intl/intl/ru/guide/components/activities.jd @@ -0,0 +1,756 @@ +page.title=Операции +page.tags=операция,намерение +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> +<h2>Содержание документа</h2> +<ol> + <li><a href="#Creating">Создание операции</a> + <ol> + <li><a href="#UI">Реализация пользовательского интерфейса</a></li> + <li><a href="#Declaring">Объявление операции в манифесте</a></li> + </ol> + </li> + <li><a href="#StartingAnActivity">Запуск операции</a> + <ol> + <li><a href="#StartingAnActivityForResult">Запуск операции для получения результата</a></li> + </ol> + </li> + <li><a href="#ShuttingDown">Завершение операции</a></li> + <li><a href="#Lifecycle">Управление жизненным циклом операций</a> + <ol> + <li><a href="#ImplementingLifecycleCallbacks">Реализация обратных вызовов жизненного цикла</a></li> + <li><a href="#SavingActivityState">Сохранение состояния операции</a></li> + <li><a href="#ConfigurationChanges">Обработка изменений в конфигурации</a></li> + <li><a href="#CoordinatingActivities">Согласование операций</a></li> + </ol> + </li> +</ol> + +<h2>Ключевые классы</h2> +<ol> + <li>{@link android.app.Activity}</li> +</ol> + +<h2>См. также:</h2> +<ol> + <li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">Задачи и стек +переходов назад</a></li> +</ol> + +</div> +</div> + + + +<p>{@link android.app.Activity} — это компонент приложения, который выдает экран, + и с которым пользователи могут взаимодействовать для выполнения каких-либо действий, например набрать номер телефона, сделать фото, отправить письмо или +просмотреть карту. Каждой операции присваивается окно для прорисовки соответствующего пользовательского интерфейса. Обычно окно +отображается во весь экран, однако его размер может быть меньше, и оно может размещаться поверх других +окон.</p> + +<p> Как правило, приложение состоит из нескольких операций, которые слабо +связаны друг с другом. Обычно одна из операций в приложении обозначается как «основная», +предлагаемая пользователю при первом запуске приложения. В свою очередь, каждая +операция может запустить другую операцию для выполнения различных действий. Каждый раз, когда +запускается новая операция, предыдущая операция останавливается, однако система сохраняет ее +в стеке («стек переходов назад»). При запуске новой операции она помещается в стек переходов назад и +отображается для пользователя. Стек переходов назад работает по принципу «последним вошёл — первым вышел», +поэтому после того как пользователь завершил текущую операцию и нажал кнопку <em>Назад</em>, текущая операция +удаляется из стека (и уничтожается), и возобновляется предыдущая операция. (Подробные сведения о стеке +переходов назад представлены в статье <a href="{@docRoot}guide/components/tasks-and-back-stack.html">Задачи и стек +переходов назад</a>.)</p> + +<p>Когда операция останавливается по причине запуска новой операции, для уведомления об изменении ее состояния +используются методы обратного вызова жизненного цикла операции. +Существует несколько таких методов, которые может принимать операция вследствие изменения своего состояния +— создание операции, ее остановка, возобновление или уничтожение системой; также +каждый обратный вызов представляет возможность выполнить определенное действие, +подходящее для соответствующего изменения состояния. Например, в случае остановки операция должна освободить любые +крупные объекты, например, подключение к сети или базе данных. При возобновлении операции вы можете +повторно получить необходимые ресурсы и возобновить выполнение прерванных действий. Такие изменения состояния +являются частью жизненного цикла операции.</p> + +<p>Далее в этом документе рассматриваются основы создания и использования операций, +включая полное описание жизненного цикла операции, чтобы вы могли лучше понять, как следует управлять +переходами между различными состояниями операции.</p> + + + +<h2 id="Creating">Создание операции</h2> + +<p>Чтобы создать операцию, сначала необходимо создать подкласс класса {@link android.app.Activity} (или +воспользоваться существующим его подклассом). В таком подклассе необходимо реализовать методы обратного вызова, которые +вызывает система при переходе операции из одного состояния своего жизненного цикла в другое, например при +создании, остановке, возобновлении или уничтожении операции. Вот два наиболее важных метода +обратного вызова:</p> + +<dl> + <dt>{@link android.app.Activity#onCreate onCreate()}</dt> + <dd>Этот метод необходимо обязательно реализовать, поскольку система вызывает его при создании вашей +операции. В своей реализации вам необходимо инициализировать ключевые компоненты +операции. + Наиболее важно именно здесь вызвать {@link android.app.Activity#setContentView +setContentView()} для определения макета пользовательского интерфейса операции.</dd> + <dt>{@link android.app.Activity#onPause onPause()}</dt> + <dd>Система вызывает этот метод в качестве первого признака выхода пользователя из +операции (однако это не всегда означает, что операция будет уничтожена). Обычно именно здесь +необходимо применять любые изменения, которые должны быть сохранены помимо текущего сеанса работы пользователя (поскольку +пользователь может не вернуться назад).</dd> +</dl> + +<p>Существуют также и некоторые другие методы обратного вызова жизненного цикла, которые необходимо использовать для того, чтобы обеспечить +плавный переход между операциями, а также для обработки непредвиденных нарушений в работе операции, в результате которых она может быть +остановлена или даже уничтожена. Более подробное описание всех методов обратного вызова жизненного цикла представлены в разделе, +посвященном <a href="#Lifecycle">управлению жизненным циклом операций</a>.</p> + + + +<h3 id="UI">Реализация пользовательского интерфейса</h3> + +<p> Для реализации пользовательского интерфейса операции используется иерархия представлений —объектов, полученных из +класса {@link android.view.View}. Каждое представление отвечает за определенную прямоугольную область +окна операции и может реагировать на действия пользователей. Например, представлением может быть +кнопка, нажатие на которую приводит к выполнению определенного действия.</p> + +<p>В Android предусмотрен набор уже готовых представлений, которые можно использовать для создания дизайна макета и его +организации. Виджеты — это представления с визуальными (и интерактивными) элементами, например, +кнопками, текстовыми полями, чекбоксами или просто изображениями. Макеты — это представления, полученные из класса {@link +android.view.ViewGroup}, обеспечивающие уникальную модель компоновки для своих дочерних представлений, таких как линейный +макет, сетка или относительный макет. Также можно создать подкласс для классов {@link android.view.View} и +{@link android.view.ViewGroup} (или воспользоваться существующими подклассами), чтобы создать собственные виджеты и +макеты, и затем применить их к макету своей операции.</p> + +<p>Чаще всего для задания макета с помощью представлений используется XML-файл макета, сохраненный в +ресурсах приложения. Таким образом вы можете хранить дизайн пользовательского интерфейса отдельно от +исходного кода, который служит для задания поведения операции. Чтобы задать макет в качестве пользовательского интерфейса +операции, можно использовать метод {@link android.app.Activity#setContentView(int) setContentView()}, передав в него +идентификатор ресурса для макета. Однако вы также можете создать новые {@link android.view.View} в коде вашей +операции и создать иерархию представлений. Для этого вставьте {@link +android.view.View} в {@link android.view.ViewGroup}, а затем используйте этот макет, передав корневой объект +{@link android.view.ViewGroup} в метод {@link android.app.Activity#setContentView(View) +setContentView()}.</p> + +<p>Подробные сведения о создании пользовательского интерфейса см. в статье <a href="{@docRoot}guide/topics/ui/index.html">Пользовательский интерфейс</a>.</p> + + + +<h3 id="Declaring">Объявление операции в манифесте</h3> + +<p>Чтобы операция стала доступна системе, ее необходимо объявить в файле +манифеста. Для этого откройте файл манифеста и добавьте элемент <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> в +качестве дочернего для элемента +<a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>. Например:</p> + +<pre> +<manifest ... > + <application ... > + <activity android:name=".ExampleActivity" /> + ... + </application ... > + ... +</manifest > +</pre> + +<p>Существует несколько других атрибутов, которые можно включить в этот элемент, чтобы определить такие +свойства, как метка операции, значок операции или тема оформления для пользовательского интерфейса операции. +Единственным обязательным атрибутом является <a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">{@code android:name}</a> +— он определяет имя класса операции. После +публикации вашего приложения вам не следует переименовывать его, поскольку это может нарушить некоторые +функциональные возможности приложения, например, ярлыки приложения (ознакомьтесь с публикацией <a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">Вещи +, которые нельзя менять</a> в блоге разработчиков).</p> + +<p>Дополнительные сведения об объявлении операции +в манифесте см. в справке по элементу <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>.</p> + + +<h4>Использование фильтров намерений</h4> + +<p>Элемент <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code +<activity>}</a> также может задавать различные фильтры намерений — с помощью элемента <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> — для объявления того, как другие компоненты приложения +могут активировать операцию.</p> + +<p>При создании нового приложения с помощью инструментов Android SDK в заготовке операции, +создаваемой автоматически, имеется фильтр намерений, который объявляет операцию. +Эта операция реагирует на выполнение «основного» действия, и ее следует поместить в категорию переходсредства запуска. Фильтр намерений +выглядит следующим образом.</p> + +<pre> +<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> +</activity> +</pre> + +<p>Элемент <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</a> указывает, что это «основная» точка входа в приложение. Элемент <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code +<category>}</a>указывает, что эту операцию следует указать в +средстве запуска приложений системы (чтобы пользователи могли запускать эту операцию).</p> + +<p>Если приложение планируется создать самодостаточным и запретить другим приложениям активировать +его операции, то других фильтров намерений создавать не нужно. В этом случае только в одной операции +должно иметься «основное» действие, и ее следует поместить в категорию средства запуска, как в примере выше. В операциях, +которые не должны быть доступны для других приложений, не следует включать фильтры намерений. +Вы можете самостоятельно запустить такие операции с помощью явных намерений (как описывается в следующем разделе).</p> + +<p>Однако, если вам необходимо, чтобы операция реагировала на неявные намерения, +получаемые от других приложений (а также из вашего приложения), для операции необходимо определить дополнительные фильтры +намерений. Для каждого типа намерения, на который необходимо реагировать, необходимо указать объект <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a>, включающий элемент +<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</a> и необязательный элемент <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code +<category>}</a> или <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code +<data>}</a> (или оба этих элемента). Эти элементы определяют тип намерения, на который может реагировать +ваша операция.</p> + +<p>Дополнительные сведения о том, как операции могут реагировать на намерения, приведены в статье <a href="{@docRoot}guide/components/intents-filters.html">Намерения и фильтры намерений</a>. +</p> + + + +<h2 id="StartingAnActivity">Запуск операции</h2> + +<p>Для запуска другой операции достаточно вызвать метод {@link android.app.Activity#startActivity +startActivity()}, передав в него объект {@link android.content.Intent}, который описывает запускаемую +операцию. В намерении указывается либо точная операция для запуска, либо описывается +тип операции, которую вы хотите выполнить (после чего система выбирает для вас подходящую +операцию, которая +может даже находиться в другом приложении). Намерение также может содержать небольшой объем данных, +которые будут использоваться запущенной операцией.</p> + +<p>При работе с собственным приложением зачастую требуется лишь запустить нужную операцию. + Для этого необходимо создать намерение, которое явно определяет требуемую операцию +с помощью имени класса. Ниже представлен пример запуска одной операцией другой операции с именем {@code +SignInActivity}.</p> + +<pre> +Intent intent = new Intent(this, SignInActivity.class); +startActivity(intent); +</pre> + +<p>Однако в вашем приложении также может потребоваться выполнить некоторое действие, например, отправить письмо, текстовое +сообщение или обновить статус, используя данные из вашей операции. В этом случае в вашем приложении могут +отсутствовать такие действия, поэтому вы можете воспользоваться операциями +из других приложений, имеющихся на устройстве, которые могут выполнять требуемые действия. Как раз в этом случае +намерения особенно полезны — можно создать намерение, которое описывает необходимое действие, +после чего система +запускает его из другого приложения. При наличии +нескольких операций, которые могут обработать намерение, пользователь может выбирать, какое из них следует использовать. Например, +если пользователю требуется предоставить возможность отправить электронное письмо, можно создать +следующее намерение:</p> + +<pre> +Intent intent = new Intent(Intent.ACTION_SEND); +intent.putExtra(Intent.EXTRA_EMAIL, recipientArray); +startActivity(intent); +</pre> + +<p>Дополнительный компонент {@link android.content.Intent#EXTRA_EMAIL}, добавленный в намерение, представляет собой строковый массив +адресов электронной почты для отправки письма. Когда почтовая программа реагирует на это +намерение, она считывает дополнительно добавленный строковый массив и помещает имеющиеся в нем адреса в поле получателя +в окне создания письма. При этом запускается операция почтовой программы, а после того, как +пользователь завершит требуемые действия, возобновляется ваша операция.</p> + + + + +<h3 id="StartingAnActivityForResult">Запуск операции для получения результата</h3> + +<p>В некоторых случаях после запуска операции может потребоваться получить результат. Для этого +вызовите метод {@link android.app.Activity#startActivityForResult +startActivityForResult()} (вместо {@link android.app.Activity#startActivity +startActivity()}). Чтобы получить результат после выполнения последующей +операции, реализуйте метод обратного +вызова {@link android.app.Activity#onActivityResult onActivityResult()}. По завершении последующей операции она возвращает результат в объекте {@link +android.content.Intent} +в вызванный метод {@link android.app.Activity#onActivityResult onActivityResult()}.</p> + +<p>К примеру, пользователю потребуется выбрать один из контактов, чтобы ваша операция могла +выполнить некоторые действия с информацией об этом контакте. Ниже представлен пример создания такого намерения +и обработки результата.</p> + +<pre> +private void pickContact() { + // Create an intent to "pick" a contact, as defined by the content provider URI + Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI); + startActivityForResult(intent, PICK_CONTACT_REQUEST); +} + +@Override +protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // If the request went well (OK) and the request was PICK_CONTACT_REQUEST + if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) { + // Perform a query to the contact's content provider for the contact's name + Cursor cursor = getContentResolver().query(data.getData(), + new String[] {Contacts.DISPLAY_NAME}, null, null, null); + if (cursor.moveToFirst()) { // True if the cursor is not empty + int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); + String name = cursor.getString(columnIndex); + // Do something with the selected contact's name... + } + } +} +</pre> + +<p>В этом примере демонстрируется базовая логика, которой следует руководствоваться при использовании метода {@link +android.app.Activity#onActivityResult onActivityResult()} для обработки результата +выполнения операции. Первое условие проверяет, успешен ли запрос, и если он успешен, то результат для +{@code resultCode} будет {@link android.app.Activity#RESULT_OK}; также проверяется, известен ли запрос, +для которого получен этот результат, и в этом случае {@code requestCode} соответствует +второму параметру, отправленному в метод {@link android.app.Activity#startActivityForResult +startActivityForResult()}. Здесь код обрабатывает результат выполнения операции путем запроса данных, +возвращенных в {@link android.content.Intent} (параметр {@code data}).</p> + +<p>При этом {@link +android.content.ContentResolver} выполняет запрос к поставщику контента, который возвращает объект +{@link android.database.Cursor}, обеспечивающий считывание запрошенных данных. Дополнительные сведения представлены в статье +<a href="{@docRoot}guide/topics/providers/content-providers.html">Поставщики контента</a>.</p> + +<p>Дополнительные сведения об использовании намерений см. в статье <a href="{@docRoot}guide/components/intents-filters.html">Намерения и фильтры +намерений</a>.</p> + + +<h2 id="ShuttingDown">Завершение операции</h2> + +<p>Для завершения операции достаточно вызвать ее метод {@link android.app.Activity#finish +finish()}. Также для завершения отдельной операции, запущенной ранее, можно вызвать метод +{@link android.app.Activity#finishActivity finishActivity()}.</p> + +<p class="note"><strong>Примечание.</strong> В большинстве случаев вам не следует явно завершать операцию +с помощью этих методов. Как указано в следующем разделе, посвященном управлению жизненным циклом операции, система +Android выполняет такое управление за вас, поэтому вам не нужно завершать ваши +собственные операции. Вызов этих методов может отрицательно сказаться на ожидаемом +поведении приложения. Их следует использовать исключительно тогда, когда вы абсолютно не хотите, чтобы пользователь возвращался к этому +экземпляру операции.</p> + + +<h2 id="Lifecycle">Управление жизненным циклом операций</h2> + +<p>Управление жизненным циклом операций путем реализации методов обратного вызова +имеет важное значение при разработке надежных +и гибких приложений. На жизненный цикл операции напрямую влияют его связи +с другими операциями, его задачами и стеком переходов назад.</p> + +<p>Существует всего три состояния операции:</p> + +<dl> + <dt><i>Возобновлена</i></dt> + <dd>Операция выполняется на переднем плане экрана и отображается для пользователя. (Это состояние +также иногда называется «Выполняется».)</dd> + + <dt><i>Приостановлена</i></dt> + <dd>На переднем фоне выполняется другая операция, которая отображается для пользователя, однако эта операция по-прежнему не скрыта. То есть +поверх текущей операции отображается другая операция, частично прозрачная или не занимающая +полностью весь экран. Приостановленная операция полностью активна (объект {@link android.app.Activity} +по-прежнему находится в памяти, в нем сохраняются все сведения о состоянии и информация об элементах, и он также остается связанным с +диспетчером окон), однако в случае острой нехватки памяти система может завершить ее.</dd> + + <dt><i>Остановлена</i></dt> + <dd>Операция полностью перекрывается другой операцией (теперь она выполняется в +фоновом режиме). Остановленная операция по-прежнему активна (объект {@link android.app.Activity} +по-прежнему находится в памяти, в нем сохраняются все сведения о состоянии и информация об элементах, но объект больше <em>не</em> +связан с диспетчером окон). Однако операция больше не видна пользователю, и в случае нехватки памяти система +может завершить ее.</dd> +</dl> + +<p>Если операция приостановлена или полностью остановлена, система может очистить ее из памяти путем +завершения самой операции (с помощью метода {@link android.app.Activity#finish finish()}) или просто завершить ее +процесс. В случае повторного открытия операции (после ее завершения) ее потребуется создать +полностью.</p> + + + +<h3 id="ImplementingLifecycleCallbacks">Реализация обратных вызовов жизненного цикла</h3> + +<p>При переходе операции из одного вышеописанного состояния в другое, уведомления об этом +реализуются через различные методы обратного вызова. Все методы обратного вызова представляют собой привязки, которые +можно переопределить для выполнения подходящего действия при изменении состояния операции. Указанная ниже базовая +операция включает каждый из основных методов жизненного цикла.</p> + + +<pre> +public class ExampleActivity extends Activity { + @Override + public void {@link android.app.Activity#onCreate onCreate}(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // The activity is being created. + } + @Override + protected void {@link android.app.Activity#onStart onStart()} { + super.onStart(); + // The activity is about to become visible. + } + @Override + protected void {@link android.app.Activity#onResume onResume()} { + super.onResume(); + // The activity has become visible (it is now "resumed"). + } + @Override + protected void {@link android.app.Activity#onPause onPause()} { + super.onPause(); + // Another activity is taking focus (this activity is about to be "paused"). + } + @Override + protected void {@link android.app.Activity#onStop onStop()} { + super.onStop(); + // The activity is no longer visible (it is now "stopped") + } + @Override + protected void {@link android.app.Activity#onDestroy onDestroy()} { + super.onDestroy(); + // The activity is about to be destroyed. + } +} +</pre> + +<p class="note"><strong>Примечание.</strong> При реализации этих методов жизненного цикла +всегда вызывайте реализацию суперкласса, прежде чем выполнять какие-либо действия, как показано в примерах выше.</p> + +<p>Вместе все эти методы определяют весь жизненный цикл операции. С помощью реализации этих +методов можно отслеживать три вложенных цикла в жизненном цикле операции: </p> + +<ul> +<li><b>Весь жизненный цикл</b> операции происходит между вызовом метода {@link +android.app.Activity#onCreate onCreate()} и вызовом метода {@link +android.app.Activity#onDestroy}. Ваша операция должна выполнить настройку +«глобального» состояния (например, определение макета) в методе {@link android.app.Activity#onCreate onCreate()}, а затем +освободить все оставшиеся в {@link android.app.Activity#onDestroy} ресурсы. Например, если в вашей операции +имеется поток, выполняющийся в фоновом режиме, для загрузки данных по сети, операция может создать +такой поток в методе {@link android.app.Activity#onCreate onCreate()}, а затем остановить его в методе {@link +android.app.Activity#onDestroy}.</li> + +<li><p><b>Видимый жизненный цикл</b> операции происходит между вызовами методов {@link +android.app.Activity#onStart onStart()} и {@link +android.app.Activity#onStop onStop()}. В течение этого времени операция +отображается на экране, где пользователь может взаимодействовать с ней. Например, метод {@link android.app.Activity#onStop onStop()} вызывается в +случае, когда запускается новая операция, а текущая больше не отображается. В промежутке между вызовами этих двух методов можно +сохранить ресурсы, необходимые для отображения операции для пользователя. Например, можно зарегистрировать объект +{@link android.content.BroadcastReceiver} в методе {@link +android.app.Activity#onStart onStart()} для отслеживания изменений, влияющих на пользовательский интерфейс, а затем отменить его регистрацию +в методе {@link android.app.Activity#onStop onStop()}, когда пользователь больше не видит +отображаемого. В течение всего жизненного цикла операции система может несколько раз вызывать методы {@link android.app.Activity#onStart onStart()} и {@link +android.app.Activity#onStop onStop()}, поскольку +операция то отображается для пользователя, то скрывается от него.</p></li> + +<li><p><b>Жизненный цикл операции, выполняемый на переднем плане</b>, происходит между вызовами методов {@link +android.app.Activity#onResume onResume()} и {@link android.app.Activity#onPause +onPause()}. В течение этого времени операция выполняется на фоне всех прочих операций и +отображается для пользователя. Операция может часто уходить в фоновый режим и выходить из него — например, +метод {@link android.app.Activity#onPause onPause()} вызывается при переходе устройства в спящий режим или +при появлении диалогового окна. Поскольку переход в это состояние может выполняться довольно часто, код в этих двух методах +должен быть легким, чтобы не допустить медленных переходов и не заставлять пользователя ждать.</p></li> +</ul> + +<p>На рисунке 1 иллюстрируются проходы и пути, которые операция может пройти между состояниями. +Прямоугольниками обозначены методы обратного вызова, которые можно реализовать для выполнения действий между переходами операции из одного +состояния в другое. <p> + +<img src="{@docRoot}images/activity_lifecycle.png" alt="" /> +<p class="img-caption"><strong>Рисунок 1.</strong> Жизненный цикл операции.</p> + +<p>Эти же методы жизненного цикла перечислены в таблице 1, в которой подробно описан каждый метод +обратного вызова и указано его место в +жизненном цикле операции в целом, включая сведения о том, может ли система завершить операцию по завершении +метода обратного вызова.</p> + +<p class="table-caption"><strong>Таблица 1.</strong> Сводные сведения о методах обратного вызова +жизненного цикла операции.</p> + +<table border="2" width="85%" frame="hsides" rules="rows"> +<colgroup align="left" span="3"></colgroup> +<colgroup align="left"></colgroup> +<colgroup align="center"></colgroup> +<colgroup align="center"></colgroup> + +<thead> +<tr><th colspan="3">Метод</th> <th>Описание</th> <th>Завершаемый?</th> <th>Следующий</th></tr> +</thead> + +<tbody> +<tr> + <td colspan="3" align="left"><code>{@link android.app.Activity#onCreate onCreate()}</code></td> + <td>Вызывается при первом создании операции. + Здесь необходимо настроить все обычные статические элементы — +создать представления, привязать данные и т. д. Этот метод передает +объект Bundle, содержащий предыдущее состояние операции (если +такое состояние было зафиксировано ранее; см. раздел <a href="#actstate">Сохранение состояния +операции</a>). + <p>За ним всегда следует метод {@code onStart()}.</p></td> + <td align="center">Нет</td> + <td align="center">{@code onStart()}</td> +</tr> + +<tr> + <td rowspan="5" style="border-left: none; border-right: none;"> </td> + <td colspan="2" align="left"><code>{@link android.app.Activity#onRestart +onRestart()}</code></td> + <td>Вызывается после остановки операции непосредственно перед ее +повторным запуском. + <p>За ним всегда следует метод {@code onStart()}.</p></td> + <td align="center">Нет</td> + <td align="center">{@code onStart()}</td> +</tr> + +<tr> + <td colspan="2" align="left"><code>{@link android.app.Activity#onStart onStart()}</code></td> + <td>Вызывается непосредственно перед тем, как операция становится видимой для пользователя. + <p>За ним следует метод {@code onResume()}, если операция +переходит на передний план, или метод {@code onStop()}, если она становится скрытой.</p></td> + <td align="center">Нет</td> + <td align="center">{@code onResume()} <br/>или<br/> {@code onStop()}</td> +</tr> + +<tr> + <td rowspan="2" style="border-left: none;"> </td> + <td align="left"><code>{@link android.app.Activity#onResume onResume()}</code></td> + <td>Вызывается непосредственно перед тем, как операция +начинает взаимодействие с пользователем. На этом этапе операция находится в самом +верху стека операций, и в нее поступают данные, вводимые пользователем. + <p>За ним всегда следует метод {@code onPause()}.</p></td> + <td align="center">Нет</td> + <td align="center">{@code onPause()}</td> +</tr> + +<tr> + <td align="left"><code>{@link android.app.Activity#onPause onPause()}</code></td> + <td>Вызывается, когда система собирается возобновить +другую операцию. Этот метод обычно используется для записи несохраненных изменений +в постоянное место хранения данных, остановки анимаций и других элементов, которые могут +использовать ресурсы ЦП и т. д. Здесь крайне важна оперативность, поскольку +следующая операция не будет возобновлена до тех пор, пока она не будет возвращена на передний план. + <p>За ним следует либо метод {@code onResume()}, если операция +возвращается на передний план, либо метод {@code onStop()}, если операция +становится скрытой для пользователя.</td> + <td align="center"><strong style="color:#800000">Да</strong></td> + <td align="center">{@code onResume()} <br/>или<br/> {@code onStop()}</td> +</tr> + +<tr> + <td colspan="2" align="left"><code>{@link android.app.Activity#onStop onStop()}</code></td> + <td>Вызывается в случае, когда операция больше не отображается для пользователя. Это может +произойти по причине того, что операция уничтожена, или ввиду возобновления поверх нее другой операции +(существующей или новой). + <p>За ним следует либо метод {@code onRestart()}, если +операция возобновляет взаимодействие с пользователем, либо метод +{@code onDestroy()}, если операция переходит в фоновый режим.</p></td> + <td align="center"><strong style="color:#800000">Да</strong></td> + <td align="center">{@code onRestart()} <br/>или<br/> {@code onDestroy()}</td> +</tr> + +<tr> + <td colspan="3" align="left"><code>{@link android.app.Activity#onDestroy +onDestroy()}</code></td> + <td>Вызывается перед тем, как операция будет уничтожена. Это финальный вызов, +который получает операция. Его можно вызвать либо по причине +завершения операции (вызов метода <code>{@link android.app.Activity#finish + finish()}</code>), либо ввиду временного уничтожения системой этого +экземпляра операции с целью освободить место. Чтобы различить эти два +сценария, используется метод <code>{@link + android.app.Activity#isFinishing isFinishing()}</code>.</td> + <td align="center"><strong style="color:#800000">Да</strong></td> + <td align="center"><em>Ничего</em></td> +</tr> +</tbody> +</table> + +<p>В столбце «Завершаемый?» указывается, может ли система +в любое время завершить процесс, содержащий операцию, <em>после возвращения метода</em> без +выполнения другой строки кода операции. Для трех методов в этом столбце указано «Да»: ({@link +android.app.Activity#onPause +onPause()}, {@link android.app.Activity#onStop onStop()} и {@link android.app.Activity#onDestroy +onDestroy()}). Поскольку метод {@link android.app.Activity#onPause onPause()} является первым из +этих трех после создания операции, метод {@link android.app.Activity#onPause onPause()} является +последним, который гарантированно будет вызван перед тем, как процесс <em>можно будет</em> завершить; если +системе потребуется срочно восстановить память в случае аварийной ситуации, то методы {@link +android.app.Activity#onStop onStop()} и {@link android.app.Activity#onDestroy onDestroy()} вызвать +не удастся. Поэтому следует воспользоваться {@link android.app.Activity#onPause onPause()}, чтобы записать +критически важные данные (такие как правки пользователя) в хранилище постоянных данных. Однако следует внимательно подходить к выбору информации, +которую необходимо сохранить во время выполнения метода {@link android.app.Activity#onPause onPause()}, поскольку любая блокировка +процедур в этом методе может вызвать блокирование перехода к следующей операции и тормозить работу +пользователя.</p> + +<p> Методы, для которых в столбце <b>Завершаемый?</b> указано «Нет», защищают процесс, содержащий операцию +, от завершения сразу с момента их вызова. Поэтому завершить операцию +можно в период между возвратом {@link android.app.Activity#onPause onPause()} и вызовом +{@link android.app.Activity#onResume onResume()}. Его снова не удастся завершить, пока снова не будет вызван и возвращен +{@link android.app.Activity#onPause onPause()}. </p> + +<p class="note"><strong>Примечание.</strong> Операцию, которую технически невозможно завершить в соответствии с определением +в таблице 1, по-прежнему может завершить система, однако это может произойти только в +чрезвычайных ситуациях, когда нет другой возможности. Случаи, когда возможно завершение операции, +более подробно рассматриваются в статье<a href="{@docRoot}guide/components/processes-and-threads.html">Процессы и +потоки</a>.</p> + + +<h3 id="SavingActivityState">Сохранение состояния операции</h3> + +<p>В обзорных сведениях об <a href="#Lifecycle">управлении жизненным циклом операции</a> кратко упоминается, +что +в случае приостановки или полной остановки операции ее состояние сохраняется. Это действительно так, поскольку +объект {@link android.app.Activity} при этом по-прежнему находится в памяти +, и вся информация о ее элементах и текущем состоянии по-прежнему активна. Поэтому любые +вносимые пользователем в операции изменения сохраняются, и когда операция возвращается на передний план +(когда она «возобновляется»), эти изменения остаются в этом объекте.</p> + +<p>Однако когда система уничтожает операцию в целях восстановления памяти, объект {@link +android.app.Activity} уничтожается, в результате чего системе не удается просто восстановить состояние операции для взаимодействия +с ней. Вместо этого системе необходимо повторно создать объект {@link android.app.Activity}, если пользователь +возвращается к нему. Но пользователю неизвестно, +что система уже уничтожила операцию и создала ее повторно, поэтому, возможно, +он ожидает, что операция осталась прежней. В этой ситуации можно обеспечить +сохранение важной информации о состоянии операции путем реализации дополнительного +метода обратного вызова, который позволяет сохранить информацию о вашей операции: {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()}.</p> + +<p>Прежде чем сделать операцию доступной для уничтожения, система вызывает метод +{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}. Система передает в этот метод объект +{@link android.os.Bundle}, в котором можно сохранить +информацию о состоянии операции в виде пар «имя-значение», используя для этого такие методы, как {@link +android.os.Bundle#putString putString()} и {@link +android.os.Bundle#putInt putInt()}. Затем, если система завершает процесс +вашего приложения и пользователь возвращается к вашей операции, система повторно создает операцию и передает объект +{@link android.os.Bundle} в оба метода: {@link android.app.Activity#onCreate onCreate()} и {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}. С помощью любого из этих +методов можно извлечь из объекта {@link android.os.Bundle} сохраненную информацию о состоянии операции и восстановить +ее. Если такая информация отсутствует, то объект {@link +android.os.Bundle} передается с нулевым значением (это происходит в случае, когда операция +создается в первый раз).</p> + +<img src="{@docRoot}images/fundamentals/restore_instance.png" alt="" /> +<p class="img-caption"><strong>Рисунок 2.</strong> Два способа возврата операции к отображению для пользователя +в неизмененном состоянии: уничтожение операции с последующим ее повторным созданием, когда операция должна восстановить свое +ранее сохраненное состояние, или остановка операции и ее последующее восстановление в неизмененном +состоянии.</p> + +<p class="note"><strong>Примечание.</strong> Нет никаких гарантий, что метод {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} будет вызван до того, как ваша +операция будет уничтожена, поскольку существуют случаи, когда нет необходимости сохранять состояние +(например, когда пользователь покидает вашу операцию нажатием кнопки <em>Назад</em>, +явным образом +закрывая ее). Если система вызывает метод {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()}, она делает это до вызова метода {@link +android.app.Activity#onStop onStop()} и, возможно, перед вызовом метода {@link android.app.Activity#onPause +onPause()}.</p> + +<p>Однако, даже если вы ничего не предпринимаете и не реализуете метод {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()}, часть состояния операции восстанавливается +реализацией по умолчанию метода {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} класса {@link android.app.Activity}. В частности, реализация +по умолчанию вызывает соответствующий метод {@link +android.view.View#onSaveInstanceState onSaveInstanceState()} для каждого объекта {@link +android.view.View} в макете, благодаря чему каждое представление может предоставлять ту информацию о себе, +которую следует сохранить. Почти каждый виджет в платформе Android реализует этот метод необходимым +для себя способом так, что любые видимые изменения в пользовательском интерфейсе автоматически сохраняются и восстанавливаются при повторном +создании операции. Например, виджет {@link android.widget.EditText} сохраняет любой текст, +введенный пользователем, а виджет {@link android.widget.CheckBox} сохраняет информацию о том, был +ли установлен флажок. От вас требуется лишь указать уникальный идентификатор (с атрибутом <a href="{@docRoot}guide/topics/resources/layout-resource.html#idvalue">{@code android:id}</a>) +для каждого виджета, состояние которого необходимо сохранить. Если виджету не присвоен идентификатор, то системе +не удастся сохранить его состояние.</p> + +<div class="sidebox-wrapper"> +<div class="sidebox"> +<p>Вы также можете явно отключить сохранение информации о состоянии представления в макете. Для этого задайте для атрибута +{@link android.R.attr#saveEnabled android:saveEnabled} значение {@code "false"} или вызовите метод +{@link android.view.View#setSaveEnabled setSaveEnabled()}. Обычно отключать сохранение такой информации не требуется +, однако это может потребоваться в случаях, когда восстановить состояние пользовательского интерфейса операции необходимо другим образом.</p> +</div> +</div> + +<p>Несмотря на то что реализация метода {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} по умолчанию позволяет сохранить полезную информацию о +пользовательском интерфейсе вашей операции, вам по-прежнему может потребоваться переопределить ее для сохранения дополнительной информации. +Например, может потребоваться сохранить значения элементов, которые изменялись в течение жизненного цикла операции (которые могут +коррелировать со значениями, восстановленными в пользовательском интерфейсе, однако элементы, содержащие эти значения пользовательского интерфейса, по умолчанию не +были восстановлены).</p> + +<p>Поскольку реализация метода {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} по умолчанию позволяет сохранить состояние пользовательского интерфейса, в случае +, если вы переопределите метод с целью сохранить дополнительную информацию о состоянии, перед выполнением каких-либо действий вы всегда можете вызвать реализацию +суперкласса для метода +{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}. Точно так же реализацию суперкласса {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} следует вызывать в случае ее переопределения, чтобы реализация по умолчанию могла сохранить +состояния представлений.</p> + +<p class="note"><strong>Примечание.</strong> Поскольку вызов метода {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()} не гарантируется, +вам следует использовать его только для записи переходного состояния операции (состояние +пользовательского интерфейса) — никогда не используйте его для хранения постоянных данных. Вместо этого используйте метод {@link +android.app.Activity#onPause onPause()} для сохранения постоянных данных (например, тех, которые следует сохранить в +базу данных), когда пользователь покидает операцию.</p> + +<p>Отличный способ проверить возможность вашего приложения восстанавливать свое состояние — это просто повернуть +устройство для изменения ориентации экрана. При изменении ориентации экрана система +уничтожает и повторно создает операцию, чтобы применить альтернативные ресурсы, которые могут быть +доступны для новой конфигурации экрана. Только по одной этой причине крайне важно, чтобы ваша операция +могла полностью восстанавливать свое состояние при ее повторном создании, поскольку пользователи постоянно работают с +приложениями в разных ориентациях экрана.</p> + + +<h3 id="ConfigurationChanges">Обработка изменений в конфигурации</h3> + +<p>Некоторые конфигурации устройств могут изменяться в режиме выполнения +(например, ориентация экрана, доступность клавиатуры и язык). В таких случаях Android повторно создает выполняющуюся операцию +(система сначала вызывает метод {@link android.app.Activity#onDestroy}, а затем сразу же вызывает метод {@link +android.app.Activity#onCreate onCreate()}). Такое поведение позволяет +приложению учитывать новые конфигурации путем автоматической перезагрузки в приложение +альтернативных ресурсов, которые вы предоставили (например, различные макеты для +разных ориентаций и экранов разных размеров).</p> + +<p>Если операция разработана должным образом и должным образом поддерживает перезапуск после изменения ориентации экрана и +восстановление своего состояния, как описано выше, ваше приложение можно считать более устойчивым к другим +непредвиденным событиям в жизненном цикле операции.</p> + +<p>Лучший способ обработки такого перезапуска +— сохранить и восстановить состояние операции с помощью методов {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} и {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} (или {@link +android.app.Activity#onCreate onCreate()}), как описано в предыдущем разделе.</p> + +<p>Дополнительные сведения об изменениях конфигурации, происходящих в режиме выполнения, и о способах их обработки +представлены в руководстве<a href="{@docRoot}guide/topics/resources/runtime-changes.html">Обработка изменений в режиме +выполнения</a>.</p> + + + +<h3 id="CoordinatingActivities">Согласование операций</h3> + + <p>Когда одна операция запускает другую, в жизненных циклах обеих из них происходит переход из одного состояния в другое. Первая операция +приостанавливается и заврешается (однако она не будет остановлена, если она по-прежнему видима на фоне), а вторая +операция создается. В случае, если эти операции обмениваются данным, сохраненными на диске или в другом месте, важно понимать, +что первая операция не останавливается полностью до тех пор, пока не будет создана вторая операция. +Наоборот, процесс запуска второй операции накладывается на процесс остановки первой +операции.</p> + +<p>Порядок обратных вызовов жизненного цикла четко определен, в частности, когда в одном и том же процессе находятся две операции +, и одна из них запускает другую. Ниже представлен порядок выполнения действий в случае, когда операция +А запускает операцию Б. </p> + +<ol> +<li>Выполняется метод {@link android.app.Activity#onPause onPause()} операции А.</li> + +<li>Последовательно выполняются методы {@link android.app.Activity#onCreate onCreate()}, {@link +android.app.Activity#onStart onStart()} и {@link android.app.Activity#onResume onResume()} +операции Б. (Теперь для пользователя отображается операция Б.)</li> + +<li>Затем, если операция A больше не отображается на экране, выполняется ее метод {@link +android.app.Activity#onStop onStop()}.</li> +</ol> + + <p>Такая предсказуемая последовательность выполнения обратных вызовов жизненного цикла позволяет управлять переходом +информации из одной операции в другую. Например, если после остановки первой операции требуется выполнить запись в базу данных, +чтобы следующая операция могла считать их, то запись в базу данных следует выполнить +во время выполнения метода {@link android.app.Activity#onPause onPause()}, а не во время выполнения метода {@link +android.app.Activity#onStop onStop()}.</p> + +<!-- +<h2>Beginner's Path</h2> + +<p>For more information about how Android maintains a history of activities and +enables user multitasking, continue with the <b><a +href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back +Stack</a></b> document.</p> +--> |