Главная страница
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
qrcode

Программирование под Android. Для профессионалов


Скачать 19.35 Mb.
НазваниеПрограммирование под Android. Для профессионалов
АнкорBrayn Khardi Bill Fillips - Programmirovanie po.
Дата23.05.2017
Размер19.35 Mb.
Формат файлаpdf
Имя файлаBrayn_Khardi_Bill_Fillips_-_Programmirovanie_po.pdf
оригинальный pdf просмотр
ТипДокументы
#21061
страница9 из 55
КаталогОбразовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
1   ...   5   6   7   8   9   10   11   12   ...   55
Глава 3. Жизненный цикл Activity
Рис. 3.5. Создание фильтра в LogCat
Щелкните на кнопке
OK
; открывается новая вкладка, в которой выводятся только сообщения с меткой
QuizActivity
(рис. 3.6). После запуска GeoQuiz были вызваны три метода жизненного цикла и был создан исходный экземпляр
QuizActivity
Рис. 3.6. Запуск GeoQuiz сопровождается созданием, запуском и продолжением активности
(Если вы не видите отфильтрованный список, выберите фильтр
QuizActivity на левой панели LogCat.)
А теперь немного поэкспериментируем. Нажмите на устройстве кнопку
Back
, а за- тем проверьте вывод LogCat. Активность приложения получила вызовы onPause()
, onStop()
и onDestroy()
Рис. 3.7. Нажатие кнопки Back приводит к уничтожению активности
Нажимая кнопку
Back
, вы сообщаете Android: «Я завершил работу с активностью, и она мне больше не нужна». Android уничтожает активность, чтобы не избежать неэффективного расходования ограниченных ресурсов устройства.

Использование LogCat
77
Перезапустите приложение GeoQuiz. Нажмите кнопку
Home и проверьте вывод
LogCat. Ваша активность получила вызовы onPause()
и onStop()
, но не вызов onDestroy()
Рис. 3.8. Нажатие кнопки Home останавливает активность
Вызовите на устройстве диспетчер задач. На новых устройствах для этого следует нажать кнопку
Recents рядом с кнопкой
Home
(рис. 3.9). На устройствах без кнопки
Recents выполните долгое нажатие кнопки
Home
Кнопка Recents
Кнопка Home
Кнопка Back
Рис. 3.9. Кнопки Home, Back и Recents
В диспетчере задач нажмите на приложении GeoQuiz и проверьте вывод LogCat.
Активность запускается и продолжает работу, но создавать ее не нужно.
Нажатие кнопки
Home сообщает Android: «Я сейчас займусь другим делом, но потом могу вернуться». Android приостанавливает активность, но старается не уничтожать ее на случай возвращения.

78
Глава 3. Жизненный цикл Activity
Тем не менее существование остановленной активности не гарантировано. Если системе потребуется занятая память, она уничтожает остановленные активности.
Наконец, представьте маленькое временное окно, которое только частично за- крывает активность. При появлении такого окна находящаяся за ним активность приостанавливается и взаимодействие с ней невозможно. Выполнение активности будет продолжено, когда временное окно будет закрыто.
Далее в этой книге мы будем переопределять различные методы жизненного цикла активности для решения реальных задач. При этом применение каждого метода будет рассматриваться более подробно.
Повороты и жизненный цикл активности
А теперь вернемся к ошибке, обнаруженной в конце главы 2. Запустите GeoQuiz, нажмите кнопку
Next для перехода к следующему вопросу, а затем поверните устройство. (Чтобы имитировать поворот в эмуляторе, нажмите
Control+F12/Ctrl+F12
).
После поворота GeoQuiz снова выводит первый вопрос. Чтобы понять, почему это произошло, просмотрите вывод LogCat.
Рис. 3.10. QuizActivity умирает и возрождается
Когда вы поворачиваете устройство, экземпляр
QuizActivity
, который вы видели, уничтожается, и вместо него создается новый экземпляр. Снова поверните устрой- ство — происходит еще один цикл уничтожения и возрождения.
Из-за этого и возникает ошибка. При каждом создании нового экземпляра
QuizAc- tivity переменная mCurrentIndex инициализируется 0, а пользователь начинает с первого вопроса. Вскоре мы исправим ошибку, но сначала повнимательнее раз- беремся, почему это происходит.
Конфигурации устройств
и альтернативные ресурсы
Поворот приводит к изменению конфигурации устройства. Конфигурация устрой- ства представляет собой набор характеристик, описывающих текущее состояние конкретного устройства. К числу характеристик, определяющих конфигурацию,

Создание макета для альбомной ориентации
79
относится ориентация экрана, плотность пикселов, размер экрана, тип клавиатуры, режим стыковки, язык и многое другое.
Как правило, приложения предоставляют альтернативные ресурсы для разных конфигураций устройств. Пример такого рода нам уже встречался — вспомните, как мы включали в проект несколько изображений стрелки для разной плотности пикселов.
Плотность пикселов является фиксированным компонентом конфигурации устройства; она не может измениться во время выполнения. Напротив, некоторые компоненты (такие, как ориентация) могут изменяться при выполнении.
При изменении конфигурации во время выполнения может оказаться, что при- ложение содержит ресурсы, лучше подходящие для новой конфигурации. Чтобы увидеть, как работает этот механизм, мы создадим альтернативный ресурс, который
Android найдет и использует при изменении ориентации экрана.
Создание макета для альбомной ориентации
Сверните панель LogCat. (Если вместо этого вы случайно закроете панель LogCat, ее всегда можно открыть заново командой
Window

Show
View...
)
Затем на панели
Package
Explorer щелкните правой кнопкой мыши на каталоге res и создайте новую папку. Присвойте ей имя layout-land
Рис. 3.11. Создание новой папки

80
Глава 3. Жизненный цикл Activity
Скопируйте файл activity_quiz.xml из res/layout/
в res/layout-land/
. Теперь в приложении имеются два макета: макет для альбомной ориентации и макет по умолчанию.
Оставьте имя файла без изменения. Два файла макетов должны иметь одинаковые имена, чтобы на них можно было ссылаться по одному идентификатору ресурса.
Суффикс
-land
— еще один пример конфигурационного квалификатора. По кон- фигурационным квалификаторам подкаталогов res
Android определяет, какие ресурсы лучше всего подходят для текущей конфигурации устройства. Список конфигурационных квалификаторов, поддерживаемых Android, и обозначаемых ими компонентов конфигурации устройств находится по адресу https://developer.
android.com/guide/topics/resources/providing-resources.html
. Мы вернемся к исполь- зованию конфигурационных квалификаторов в главе 15.
Когда устройство находится в альбомной ориентации, Android находит и исполь- зует ресурсы в каталоге res/layout-land
. В противном случае используются ресурсы по умолчанию из каталога res/layout/
Внесем некоторые изменения в альбомный макет, чтобы он отличался от макета по умолчанию. Сводка этих изменений представлена на рис. 3.12.
Рис. 3.12. Альтернативный макет для альбомной ориентации
Вместо
LinearLayout будет использоваться
FrameLayout
— простейшая разно- видность
ViewGroup без определенного способа размещения потомков. В этом макете дочерние представления будут размещаться в соответствии с атрибутом android:layout_gravity
Атрибут android:layout_gravity необходим виджетам
TextView
,
LinearLayout и
Button
. Потомки
Button виджета
LinearLayout остаются без изменений.
Откройте файл layout-land/activity_quiz.xml и внесите необходимые изменения, руко- водствуясь рис. 3.12. Проверьте результат своей работы по листингу 3.4.

Создание макета для альбомной ориентации
81
Листинг 3.4. Настройка альбомного макета (layout-land/activity_quiz.xml)

android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
>

android:layout_width="match_parent"
android:layout_height="match_parent" >
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="24dp" />
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:orientation="horizontal" >


82
Глава 3. Жизненный цикл Activity
Android при повороте уничтожает текущий экземпляр
QuizActivity и начинает все заново, чтобы обеспечить оптимальный подбор ресурсов для новой конфи- гурации.
Рис. 3.13. QuizActivity в альбомной ориентации
Учтите, что Android уничтожает текущую активность и создает новую при каждом изменении конфигурации времени выполнения. Также во время выполнения могут происходит и другие изменения (например, изменение языка или доступности клавиатуры), но изменение в ориентации экрана является самым частым.
Сохранение данных между поворотами
Android очень старается предоставить альтернативные ресурсы в нужный момент.
Тем не менее уничтожение и повторное создание активностей при поворотах мо- жет создать проблемы — как, например, в случае с возвратом к первому вопросу в приложении GeoQuiz.
Чтобы исправить эту ошибку, экземпляр
QuizActivity
, созданный после поворота, должен знать старое значение mCurrentIndex
. Нам необходим механизм сохранения данных при изменении конфигурации времени выполнения (например, при поворо- тах). Одно из возможных решений заключается в переопределении метода
Activity protected void onSaveInstanceState(Bundle outState)
Обычно этот метод вызывается системой перед onPause()
, onStop()
и onDestroy()
Реализация по умолчанию onSaveInstanceState(…)
приказывает всем представле- ниям активности сохранить свое состояние в данных объекта
Bundle
— структуры, связывающей строковые ключи со значениями некоторых ограниченных типов.
Мы уже видели тип
Bundle
. Он передается методу onCreate(Bundle)
:
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

Переопределение onSaveInstanceState(Bundle)
83
При переопределении onCreate(…)
вы вызываете реализацию onCreate(…)
суперклас- са активности и передаете ей только что полученный объект
Bundle
. В реализации суперкласса сохраненное состояние представлений извлекается и используется для воссоздания иерархии представлений активности.
Переопределение onSaveInstanceState(Bundle)
Метод onSaveInstanceState(…)
можно переопределить так, чтобы он сохранял до- полнительные данные в
Bundle
, а затем снова загружал их в onCreate(…)
. Именно так мы организуем сохранение значения mCurrentIndex между поворотами.
Для начала добавьте в
QuizActivity.java константу, которая станет ключом в сохраня- емой паре «ключ-значение».
Листинг 3.5. Добавление ключа для сохраняемого значения (QuizActivity.java)
public class QuizActivity extends Activity {
private static final String TAG = "QuizActivity";
private static final String KEY_INDEX = "index";
Button mTrueButton;
Теперь переопределим onSaveInstanceState(…)
для записи значения mCurrentIndex в
Bundle с использованием константы в качестве ключа.
Листинг 3.6. Переопределение onSaveInstanceState(…) (QuizActivity.java)
mNextButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
mCurrentIndex = (mCurrentIndex + 1) % mAnswerKey.length; updateQuestion();
}
});
updateQuestion();
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Log.i(TAG, "onSaveInstanceState");
savedInstanceState.putInt(KEY_INDEX, mCurrentIndex);
}
Наконец, в методе onCreate(…)
следует проверить это значение, и если оно при- сутствует — присвоить его mCurrentIndex

84
Глава 3. Жизненный цикл Activity
Листинг 3.7. Проверка сохраненных данных в onCreate(…) (QuizActivity.java)
if (savedInstanceState != null) {
mCurrentIndex = savedInstanceState.getInt(KEY_INDEX, 0);
}
updateQuestion();
}
Запустите GeoQuiz и нажмите кнопку
Next
. Сколько бы поворотов устройства вы ни выполнили, вновь созданный экземпляр
QuizActivity
«вспоминает» текущий вопрос.
Учтите, что для сохранения и восстановления из
Bundle подходят примитивные типы и объекты, реализующие интерфейс
Serializable
. Создавая собственные классы, которые вы планируете сохранять в onSaveInstanceState(…)
, не забудьте реализовать
Serializable
Реализацию onSaveInstanceState(…)
желательно протестировать — особенно если вы сохраняете и восстанавливаете объекты. Повороты тестируются легко; с тести- рованием ситуаций нехватки памяти дело обстоит сложнее. В конце этой главы приведена информация о том, как имитировать уничтожение вашей активности системой Android для освобождения памяти.
Снова о жизненном цикле Activity
Переопределение onSaveInstanceState(Bundle)
используется не только при пово- ротах. Активность также может уничтожаться и в том случае, если пользователь отойдет от устройства, а Android понадобится освободить память.
Android никогда не уничтожает для освобождения памяти выполняемую активность.
Чтобы активность была уничтожена, она должна находиться в приостановленном или остановленном состоянии. Если активность приостановлена или остановлена, значит, был вызван ее метод onSaveInstanceState(…)
При вызове onSaveInstanceState(…)
данные сохраняются в объекте
Bundle
. Опе- рационная система заносит объект
Bundle в запись активности (activity record).
Чтобы понять, что собой представляет запись активности, добавим сохраненное состояние на схему жизненного цикла активности (рис. 3.14).
Когда ваша активность сохранена, объект
Activity не существует, но объект записи активности «живет» в ОС. При необходимости операционная система может вос- создать активность по записи активности.
Следует учесть, что активность может перейти в сохраненное состояние без вызова onDestroy()
. Однако вы всегда можете рассчитывать на то, что методы onPause()
и onSaveInstanceState(…)
были вызваны. Обычно метод onSaveInstanceState(…)
переопределяется для сохранения данных в
Bundle
, а onPause()
— для всех прочих операций.

Для любознательных: тестирование onSaveInstanceState(Bundle)
85
Сохранение (эк- земпляр актив- ности уничтожен; состояние актив- ности сохранено)
Пользователь возвра- щается к активности, процесс снова начи- нает работать
Приложение не существует
Остановка (прило- жение невидимо)
Выполнение (приложе- ние видимо и находится на переднем плане)
Приостановка (прило- жение видимо
Запуск Завершается или уничтожается
Android
Становится видимым для пользователя
Перестает быть видимым
Уходит с пе- реднего плана
Выходит на пе- редний план
Рис. 3.14. Полный жизненный цикл активности
В некоторых ситуациях Android не только уничтожает активность, но и полностью завершает процесс приложения. Такая ситуация может возникнуть только в том случае, если пользователь не смотрит на приложение, но она возможна. Даже в этом случае запись активности продолжает существовать и позволяет быстро переза- пустить активность при возвращении пользователя.
Когда же запись приложения пропадает? Когда пользователь нажимает кнопку
Back
, активность уничтожается — раз и навсегда. При этом запись активности теряется.
Записи активности также обычно уничтожаются при перезагрузке; также возможно их уничтожение в том случае, если они слишком долго не используются.
Для любознательных: тестирование
onSaveInstanceState(Bundle)
Переопределяя onSaveInstanceState(Bundle)
, необходимо убедиться в том, что состояние сохраняется и восстанавливается так, как предполагалось. Это легко делается в эмуляторе.

86
Глава 3. Жизненный цикл Activity
Запустите виртуальное устройство. В списке приложений на устройстве найдите приложение
Settings
. Оно присутствует в большинстве образов системы, использу- емых в эмуляторе.
Рис. 3.15. Поиск приложения Settings
Запустите приложение
Settings и выберите категорию
Development options
. В нее входит много разных настроек; установите флажок
Don’t keep activities
Запустите приложение и нажмите кнопку
Home
. Это приведет к приостановке и остановке активности. Затем остановленная активность будет уничтожена так, как если бы ОС Android решила освободить занимаемую ей память. Восстановите приложение и посмотрите, было ли состояние сохранено так, как ожидалось.
Нажатие кнопки
Back
(вместо
Home
) всегда приводит к уничтожению активности независимо от того, установлен флажок в настройках разработчика или нет. На- жатие кнопки
Back сообщает ОС, что пользователь завершил работу с активностью.
Чтобы выполнить тот же тест на физическом устройстве, необходимо установить на нем пакет Dev Tools. За дополнительной информацией обращайтесь по адресу
https://developer.android.com/tools/debugging/debugging-devtools.html

Для любознательных: методы и уровни регистрации
87
Рис. 3.16. Запрет сохранения активностей
Для любознательных: методы
и уровни регистрации
Когда вы используете класс android.util.Log для регистрации сообщений в жур- нале, вы задаете не только содержимое сообщения, но и уровень регистрации, опре- деляющий важность сообщения. Android поддерживает пять уровней регистрации
(табл. 3.1). Каждому уровню соответствует свой метод класса
Log
. Регистрация данных в журнале сводится к вызову соответствующего метода
Log
Таблица 3.1. Методы и уровни регистрации
Уровень регистрации
Метод
Примечания
ERROR
Log.e(…)
Ошибки
WARNING
Log.w(…)
Предупреждения
INFO
Log.i(…)
Информационные сообщения
DEBUG
Log.d(…)
Отладочный вывод (может фильтроваться)
VERBOSE
Log.v(…)
Только для разработчиков!

88
1   ...   5   6   7   8   9   10   11   12   ...   55

перейти в каталог файлов

Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей

Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей