Главная » Разработка для Android » СОЗДАНИЕ ПРИЛОЖЕНИ ANDROID

0

Вопросы, рассматриваемые в этом часе: проектирование типичного приложеиня Android; использование контекста приложения;

работа с деятельностями, интентами и диалоговыми окнами; журналирование информации.

Для описания компонентов приложения каждой поатформы употребляется различная терминология. Три самых выжных класса на платформе Android это: Context (Контекст), Activity (Деятельность), и Intent (Интент). Кроме этих компонентов, есть другие, также доступные разработчикам, но именно эти три компонента входят в состав практически каждого приложения Android. В этом часе мы сосредоточим ваше внимание на понимании общих черт приложений Android. Мы также рассмотрим некоторые служебные классы, которые могут помочь разработчикам в отладке приложений.

ПРОЕКТИРОВКА ТИПИЧНОГО ПРИЛОЖЕНИЯ ANDROID

Приложение Android можно представить как набор задач, каждая из которых называется деятельностью (activity). Каждая деятельность приложения имеет определенное назначение и пользовательский интерфейс. Чтобы лучше понять этот принцип на конкретном примере, составим план небольшого игрового приложения «Chippy’s Revenge».

Проектирование возможностей приложения

Проект приложения «Chippy’s Revenge» очень прост. В этой игре будет пять экранов.

•             Экран-заставка — обычная заставка с изображением логотипа и ее версии при загрузке. Во время процесса загрузки может воспроизводится фоновая музыка.

• Help — на этом экране приводятся инструкции по игре, включая описание управления, целей игры, игровой тактики, а также подсказки и советы.

Знакомое описание? Это типичный проект любого мобильною приложения для любой платформы, в данном случае игры.

КСТАТИ ________________________________________________________________

Разумеется, вы можете разработать собственный пользовательский интерфейс, какой пожелаете. Каких-либо строгих требований к интерфейсу на платформе Android нет, но при этом приложение должно быть стабильным, интерактивным и уметь взаимодейст­вовать с системой Android. Однако все успешные и наиболее популярные приложения привлекают интерес пользователей в первую очередь удобным пользовательским ин­терфейсом. Поэтому, вместо того, чтобы придумывать новый интерфейс, если есть возможность, лучше следовать приведенному выше плану. Таким образом, пользова­телю вашего приложения не придется тратить время и силы на его изучение.

Требования к деятельности приложения

•             Вы должны реализовать пять классов деятельности — по одному для каждой возможности игры.

•             SplashActivity — деятельность запуска по умолчанию. Она выводит на экран простую информацию о запускаемой игре (это может быть изображение логотипа игры) с фоновым музыкальным сопровождением в течение нескольких секунд, после которого запускается деятельность MenuActivity.

•            MenuActivity — назначение этой деятельности можно понять из се названия. В ее макете несколько кнопок, каждая из которых связана с определенной возможностью приложения. Деятельность, связанная с каждой из кнопок, запускается обработчиком события onClick ().

•              PlayActivity — основная часть логики приложения реализуется этой деятельностью. Эта деятельность выводит на экран графику во время игрового процесса, обрабатывает данные, полученные от пользователя, ведет подсчет заработанных очков и следит за всей игровой динамикой.

•             ScoresActivity — эта деятельность такая же простая, как и SplashActivity. В основном она занимается тем, что загружает данные достижении игроков в элемент пользовательского интерфейса TextView в пределах собственного макета.

У каждого класса деятельности должен быть собственный, ассоциированный с ним файл макета, хранящийся в ресурсах приложения. Вы можете использовать один файл макета деятельности ScoresActivity и HelpActivity, но обычно в этом нет необходимости. Тем не менее, если создадите один макет для двух деятельностей, то вы можете разместить фоновое изображение и текст в элементе Textview вместо файла макета.

На рис. 3.1 изображен проект игры «Chippy’s Revenge» версии 0.0.1 в виде блок-схемы.

Рис. 3.1. Проект простого приложения Android («Chippy’s Revenge»)

Реализация функциональности приложения

Теперь, когда вы понимаете, как выглядит проект типичного приложения Android, вы, возможно, задались вопросом, как функционирует такой проект на программном уровне.

Мы говорили о том, что каждая деятельность имеет собственный пользовательский интерфейс, описанный в отдельном фарше ресурса макета. Возникает несколько вопросов:

Как запустить определенную деятельность?

Имен примерное представление об игровом приложении, теперь настало время рассмотреть процесс создания приложения Android более детально. Начнем с контекста приложения.

КОНТЕКСТ ПРИЛОЖЕНИЯ

Контекст приложения — это основа всей высокоуровневой функциональности приложения. Контекст приложения служит для получения доступа к настройкам и ресурсам, используемым несколькими экземплярам деятельности.

Получить доступ к контексту приложения текущего процесса вы можете методом

getApplicationContext (), например:

Context context = getApplicationContext();

Поскольку класс Activity происходит из класса Context, вы можете ис пользовать оператор this вместо явного указания контекста приложения.

ВНИМАНИЕ! ___________________________________________________________

Контекст Activity не рекомендуется использовать во всех случаях – это можем при­вести к утечкам памяти. Обсуждение данной проблемы выходит далеко рамки книги, поэтому исчерпывающую информацию по этой теме вы можете поискать в официаль­ном блоге разработчиков Android по адресу: android-developers. blogspot.com/2009/01/avoiding-memory-leaks.html.

Как только необходимый контекст приложения был успешно получен, его можно использовать для доступа к возможностям и службам приложения.

Доступ к ресурсам приложения

Доступ к ресурсам приложения осуществляется методом getResources ( ) контекста приложения. Самый прямой способ доступа к ресурсам – через URI, определенный в автоматически сгенерированном классе R. j ava. В следующей строке кода к экземпляру строкового типа из ресурсов приложения по его идентификатору hello:

String greeting = getResources ().getString (R.string,hello);

Доступ к параметрам приложения

Получить доступ к общедоступным параметрам приложения вы сможете методом контекста приложения getSharedPreferences().Класс SharedPreferences используется для хранения данных приложения, таких как настройки конфигурации. Каждому объекту SharedPreferences распределять настройки по категориям или хранить все настройки вместе одним комплектом. Допустим, вы пользователей и игровой статистики, например количество жизней или уровень здоровья игрового персонажа. В следующем фрагменте кода создается набор общедоступных параметров GemePref, и некоторые из них сохраняются:

SharedPreferences settings = getSharedPreferences("GamePrefs", MODE_PRIVATE);

SharedPreferences.Editor prefEditor = settings.edit(); prefEditor.putString("UserName", "Spunky"); prefEditor.putBoolean("HasCredits", true); prefEditor.commit();

Таким образом, получение доступа к параметрам настройки осуществляется через объект

SharedPreferences:

SharedPreferences settings = getSharedPreferences("GamePrefs", MODE_PRIVATE);

String userName = settings.getString("UserName", "Chippy Jr. (Default)");

Доступ к другим возможностям приложения с помощью контекстов

Контекст приложения обеспечивает доступ ко многим высокоуровневым возможностям приложения. Вот задачи, которые вы можете выполнять с помощью контекста приложения:

•              запускать экземпляры Activity;

•              получать доступ к активам приложения;

•              отправлять запрос провайдеру на системном уровне (например, службе позиционирования);

•              управлять собственными файлами приложения, папками и базами данных,

•              просматривать и изменять права приложения.

Первый элемент из этого списка, запуск экземпляров Activity, возможно, самое распространенное применение контекста приложения.

РАБОТА С ДЕЯТЕЛЬНОСТЬЮ

Класс Activity — это ключевой класс каждого приложения Android. Большую часть времени вы будете определять и реализовывать деятельность для экранов вашего приложения.

В вашем игровом приложении «Chippy’s Revenge» необходимо реализовать пять различных классов Activity. В процессе игры пользователь переходит от одной деятельности к другой, взаимодействуя со средствами управления каждой деятельности.

Запуск деятельности

Существует несколько способов запуска деятельности, среди которых:

•            назначение деятельности запуска в файле манифеста; . запуск деятельности с помощью контекста приложения;

•            запуск дочерней деятельности из родительской деятельности.

НАЗНАЧЕНИЕ ДЕЯТЕЛЬНОСТИ ЗАПУСКА В ФАЙЛЕ МАНИФЕСТА

Каждое приложение Android должно иметь деятельность по умолчанию в пределах файла манифеста Android. Если вы посмотрите на файл манифеста проекта Droidl, то заметите, что деятельность DroidActivity назначена по умолчанию.

ЗНАЕТЕ ЛИ ВЫ, ЧТО… ___________________________________________________

Другие классы Activity могут быть назначены для запуска в определенных случаях. Эти вторичные точки входа конфигурируются в файле манифеста Android специаль­ными фильтрами.

В игре «Chippy’s Revenge» логично предположить, что деятельность SplashActivity будет деятельностью по умолчанию.

ЗАПУСК ДЕЯТЕЛЬНОСТИ С ПОМОЩЬЮ КОНТЕКСТА ПРИЛОЖЕНИЯ

Наиболее распространенный способ запуска деятельности — методом контекста приложения startActivity () . Этот метод принимает единственный параметр, называемый интентом. Мы еще вернемся к обсуждению это го термина, но сначала рассмотрим метод startActivity () .

В следующем фрагменте происходит вызов места startActivity () с явно указанным интентом:

startActivity(new Intent(getApplicationContext(), MenuActivity.class));

Здесь интент запрашивает запуск деятельности MenuActivity по ее классу. Этот класс должен быть реализован в любом месте пакета.

Поскольку класс MenuActivity пределен в пределах пакета данного приложения , он должен быть зарегистрирован как деятельность в пределах файла манифеста Android. Фактически вы можете использовать этот метод для запуска любой деятельности вашего приложения, однако это лишь один из нескольких способов запуска деятельности .

ЗАПУСК РОДСТВЕННОЙ ДЕЯТЕЛЬНОСТИ

Вместо запуска одной конкретной деятельности иногда может возникнуть необходимость запуска родственных деятельностей для получения требуемого результата. В этом случае используется метод Activity. startActivityForResult (). Результат вычисления будет возвращен параметром интента метода вызываемой деятельности onActivityResult () . Далее мы поговорим о передаче данных с помощью интента более подробно.

Управление состоянием деятельности

Приложения могут быть прерваны при возникновении важных событий, таких как входящий теле­фонный вызов. Так как одновременно может быть активным только одно приложение , в любой момент времени может выполняться только одна деятельность приложения.

Приложения Android кроме памяти, ресурсов и данных управляют также своим состоянием. Операционная система Android может прекратить приостановленную деятельность, находящуюся в ожидании , при низком уровне свободной памяти. Другими словами, любая развернутая деятельность может быть принудительно завершена. Это значит, что приложение Android должны запоминать свое состояние и быть готовыми к остановке или завершению в любой момент времени.

ОБРАБОТКА СОБЫТИЙ ДЕЯТЕЛЬНОСТИ

У класса Activity есть несколько обработчиков событий, которые позволяют деятельности реагировать на такие события, как приостановка и возобновление. В табл. 3.1 представлены наиболее важные методы событий.

Метод

 

 

обработки

Описание

Рекомендации

событий

 

 

onCreate()

Вызывается после запуска

Инициализирует статические данные дея­

 

или перезапуска деятель-

тельности. Связывает с необходимыми дан-

 

ности

ными или ресурсами.

 

 

Задает макет методом

 

 

setContextView()

onResume()

Вызывается при восста-

Получает монопольные ресурсы. Запускает

 

Новлении деятельности

воспроизведение любой анимации, аудио-

 

 

или видеоконтента

onPause()

Вызывается при сверты-

Сохраняет незафиксированные данные. Де-

 

вании деятельности

активирует и выпускает монопольные ре-

 

 

сурсы.

 

 

Останавливает воспроизведение всех

 

 

видео-, аудиофайлов и анимации

onDestroy()

Вызывается при заверше­

Удаляет все статические данные деятельно-

 

ния

сти. Отдает все используемые ресурсы

Основной поток часто называют потоком пользовательского интерфейса или UI-потоком, т. к. именно здесь происходит внутренняя прорисовка пользовательского интерфейса. Деятельность должна обрабатывать события очень быстро, чтобы не блокировать основной поток. Если основной UI- поток будет заблокирован слишком долго, система

Android завершит деятельность. Особенно важно отвечать как можно быстрее во время вызова метода onPause (), когда задача с более высоким приоритетом (например, входящий телефонный звонок) приводит к свертыванию приложения.

На рис. 3.2 представлен порядок, в котором совершается обработка событий деятельности.

СОХРАНЕНИЕ СОСТОЯНИЯ ДЕЯТЕЛЬНОСТИ

Каждая деятельность может иметь собственные параметры — так же, как общедоступные параметры приложений. Вы можете получить доступ к этим параметрам с помощью метода деятельности getPreferences(). Этот механизм может быть полезен для сохранения информации о состоянии. Например, деятельность PlayActivity вашего игрового приложения может использовать эти параметры для отслеживания текущего уровня, счета, здоровья игрового персонажа и других статистических данных.

Завершение деятельностей

Чтобы завершить деятельность, вам необходимо сделать вызов метода finish(). Существует несколько различных версий этого метода в зависимости от того, завершает ли деятельность саму себя или завершает работу Другой деятельности.

Рис. 3.2. Наиболее важные методы обработки событий деятельности

В вашем приложении вы можете возвращаться с экранов Scores, Play и Help к экрану Меню завершением деятельностей ScoresActivity, PlayActivity или HelpActivity.

РАБОТА С ИНТЕНТАМИ

Объект Intent заключает в себе запрос задачи, используемый операционной системой Android. Когда метод startActivity() вызывается с параметром интента, система Android сравнивает действие Inentent с соответствующей деятельностью в системе. После этого деятельность запускается.

Система Android обрабатывает все разрешения интентов. Интент может быть строго определенным и включать запрос на определенную деятельность, подлежащую запуску. Или менее конкретным — в этом случае может быть запущена любая деятельность, соответствующая определенным критериям. Более подробную информацию о разрешении интентов вы можете найти в документации по Android.

Передача данных с помощью интентов

Интенты могут использоваться для передачи данных между деятельностями. Для этого вы должны включить дополнительные данные в пределах интента.

Для внедрения фрагментов дополнительных данных в интент используется метод putExtra () с тем типом объекта, который вы хотите включить. Согласно программным требованиям Android, каждый фрагмент дополнительных данных должен начинаться с префикса пакета (например, com. androidbook.chippy.NameOfExtra).

В следующем примере интент включает в себя дополнительную информацию — значение текущего игрового уровня, являющееся целым числом:

Intent intent=new Intent(getApplicationContext(),HelpActivi ty.class); intent.putExtra("com.androidbook.chippy.LEVEL", 23) ; startActivity(intent);

После запуска класса HelpActivity метод getintent () может использоваться для доступа к интенту. Дополнительные данные могут быть извлечены с помощью соответствующих методов. Например:

Intent callinglntent=getlntent();

int helpLevel=callingIntent.getlntExtra("com.androidbook. chippy.LEVEL",1);

Этот небольшой фрагмент данных может использоваться для получения специальных подсказок по прохождению определенного игрового уровня.

Для родительской деятельности, запустившей дочернюю                    деятельность методом

startActivityForResult(), результат как параметр будет передан методу onActivityResult() со значением Intent. Данные интента могут быть извлечены и использоваться родительской деятельностью.

Использование интентов для запуска других приложений

Первоначально приложение может запускать только те классы деятельности, которые определены в его собственном пакете. Однако если на это есть соответствующие права, приложение может также запускать внешние классы деятельности сторонних приложений.

Существуют четко определенные действия интента для многих пользовательских задач. Например, вы можете создать действия интента для выполнения таких задач как:

•            запуск встроенного веб-браузера и переход по URL;

•            запуск веб-браузера с выводом строки поиска,

•            запуск встроенного приложения для набора номера с указанием номера телефона;

•            запуск встроенного приложения Maps о указанием координат;

•            запуск сервиса Google Street View с указанием места расположения;

•            запуск встроенного приложения для работы с камерой в обычном или видеорежиме;

•            запуск средства выбора рингтона для мобильного телефона;

•            запись звука.

Ниже приведен пример создания простого интента с предопределенным действием (action_view) для запуска веб-браузера и перехода на указанный URL:

Uri address = Uri.parse("http://www.perlgurl.org"); Intent surf = new Intent(Intent.ACTION_VIEW, address); startActivity(surf);

В этом примере создается интент с предопределенным действием и некоторыми данными. Действие в этом случае означает просмотр чего-либо. В роли данных выступает URL, по котором необходимо перейти для вывода веб-страницы.

Здесь происходит запуск деятельности браузера и ее развертывание, при этом исходная деятельность вызова приостанавливается и переходит в фоновый режим. Когда пользователь заканчивает работу с браузером, кнопкой Back он может вернутся к исходной деятельности.

Приложения могут также создавать свои собственные типы интентов и позволять другим приложениям вызывать их, включая тесно интегрированные наборы приложений.

ЗНАЕТЕ ЛИ ВЫ, ЧТО..

На сайте openintents.org вы можете найти список действий интента по адресу: www.openintents.org/en/intentstable. В этот список входят действия, встроенные в Android, а также приложения сторонних разработчиков.

РАБОТА С ДИАЛОГОВЫМИ ОКНАМИ

Экраны мобильных телефонов обычно очень малы, поэтому каждый пиксель пользова­тельского интерфейса имеет большое значение. Иногда вам может понадобиться обработать простое взаимодействие с пользователем — для этого нет необходимости создавать новую деятельность. В таких случаях создание диалогового окна деятельности может быть наиболее оптимальным решением. Диалоговые окна могут быть полезными при создании простого пользовательского интерфейса, не требующего нового свободного экрана или деятельности для функционирования. Вместо этого вызываемая деятельность создает диалоговое окно, которое может иметь собственный макет, и пользовательский интерфейс с кнопками и элементами ввода.

В табл. 3.2 представлены наиболее важные методы создания и управления диалоговыми окнами деятельности.

Некоторые методы диалоговых окон класса Activity

Метод

Назначение

Activity. showDialog()

Отображает диалоговое окно по необходимости

Activity.onCreateDialog()

Обработка события первичного создания диалогового

 

окна и добавления к группе деятельностей

Activity. onPrepareDialog()

Обработка события непрерывного обновления

 

диалогового окна. Диалоговые окна создаются один

 

раз и могут быть использованы деятельностью много-

 

кратно. Этот метод позволяет диалоговым окнам об-

 

новляться непосредственно перед показом для каж-

 

дого вызова метода showDialog ()

Activity.ondismissDialog()

Отзывает диалоговое окно и возвращает к деятельно-

 

сти. Диалоговое окно остается доступным для повтор­

 

ного использования вызова метода showDialog ()

Activity.removeDialog()

Полностью удаляет диалоговое окно из пула диалого-

 

вого окна деятельности

Классы деятельности могут включать более одного диалогового окна. Каждое диалоговое окно может быть создано один раз и использоваться многократно.

Существует довольно много готовых типов диалоговых окон, доступных для использования, в дополнение к основному диалоговому окну. Вот некоторые из них:

AlertDialog, CharacterPickerDialog, DatePickerDialog, r o g r e s s D i a l o g и T i me P i c k e r D i a l o g .

Вы можете также создать полностью переделанное диалоговое окно с помощью метода Dialog. setContentView () и XML-файла макета. Для получения доступа к средствам управления диалогового окна используется метод Dialog. findViewById

ЖУРНАЛИРОВАНИЕ ДАННЫХ ПРИЛОЖЕНИЯ

Android предоставляет полезный класс утилиты журналирования android.util.Log. Записи журнала сортируются по релевантности (и подробности) с наиболее серьезными ошибками. В табл. 3.3 перечислены некоторые из часто используемых методов журналирования класса Log.

Таблица 3.3

Наиболее часто используемые методы журналирования

Метод

Назначение

Log.e()

Журналирование ошибок

Log.w()

Журналирование предупреждений

Log.i()

Журналирование информационных сообщений

Log.d()

Журналирование отладки

Log.v()

Журналирование подробных записей

ВНИМАНИЕ! ___________________________________________________________

Злоупотребление утилитой Log может привести к уменьшению производительности приложения. Отладка и подробное журналирование должны использоваться только при разработке и должны быть удалены перед публикацией приложения.

Первый параметр каждого метода Log — это строка, называемая тегом. Часто при программировании в Android определяют глобальную статическую переменную строкового типа для представления всего приложения или определенной деятельности приложения, чтобы фильтры журналирования могли ограничивать объем журнала только необходимыми данными.

Например, вы можете определить строковую переменную TAG следующим образом:

private static final String TAG="MyApp";

Теперь каждый раз при использовании метода Log, вы указываете этот тег. Запись журнала должна выглядеть примерно следующим образом:

Log.i(TAG, "In onCreate() callback method");

ЗНАЕТЕ ЛИ ВЫ, ЧТО… __________________________________________________

ВЫ можете использовать утилиту LogCat, входящую в состав Eclipse, для фильтрации сообщений журнала по тегу. За более подробной информацией обратитесь к приложе­нию Б.

ИТОГИ

В этом часе вы узнали, как различные приложения Android могут быть спроектированы с помощью трех компонентов приложения: Context, Activity и Intent. Каждое приложение Android включает одну или более деятельностей. Высокоуровневая функциональность приложения доступна посредством контекста приложения. Каждая деятельность выполняет определенную функцию и (обычно) имеет собственный макет или пользовательский интерфейс. Деятельность запускается, когда система Android сравнивает объект интента с наиболее подходящей деятельностью приложения, основанную на действии и информации, заданных в интенте. Интенты могут использоваться также для передачи данных от одной деятельности к другой.

В дополнение к изучению основ взаимодействия приложений Android вы научились также использовать полезные классы утилит Android, такие как журналирование приложений, которое может помочь оптимизировать разработку приложений Android и их отладку.

ВОПРОСЫ И ОТВЕТЫ

Вопрос. Как спроектировать интерактивное приложение, которое не будет завершаться при низком уровне свободной памяти?

Ответ. Приложения могут уменьшать (но не исключать) риск непредвиденного завершения при низком уровне свободной памяти путем управления состоянием деятельности. Это значит, что приложение должно использовать соответствующие обратные вызовы деятельности согласно приведенным рекомендациям. Очень важно, чтобы приложения получали ресурсы только при необходимости и высвобождали их как можно быстрее, насколько это возможно.

Вопрос. Как можно спроектировать форму ввода для приложения Android?

Ответ. Мобильные приложения должны быть готовы к внезапной остановке и возобновлению в любое время. Типичная веб-форма состоит из различных полей ввода и кнопок Submit (Отправить), Clear (Сброс), Cancel (Отмена), что не очень хорошо подходит для мобильного приложения. Вместо этого рассмотрите возможность непосредственного приема данных по мере их ввода пользователем. Это сократит использование аппаратных ресурсов для обслуживания данных к минимуму, поскольку состояние деятельности изменяется без привлечения внимания пользователя.

ПРАКТИКУМ Контрольные вопросы

1.                    Какой из этих экранов следует показывать пользователю при запуске приложения?

A.                               Экран меню.

B.                                Экран-заставка.

C.                                Экран игры.

2.                     Платформа Android обладает простым методом для сохранения настрой приложения. Правда ли это?

3.         Какой из рекомендуемых способов получения экземпляра контекста требуется многими вызовами Android?

A.                    Context context=(Context) this;

B.                    Context context=getAndroidObject (CONTEXT) ;

C.                    Context context=getApplicationContext () ;

4.         Класс android.util.Log поддерживает шесть типов журналирования. Правда ли это?

Ответы

1.         Правильный ответ: Б. Перед началом игры пользователь должен увидеть экран- заставку.

2.         Да, это так. Для сохранения простых настроек используется класс

SharedPreferences.

3.         Правильный ответ: В. Таким способом вы получаете контекст, привязанный к приложению. Использование контекста деятельности, как в варианте А, также допустимо, но не рекомендуется.

4.         Нет. Класс Log поддерживает пять типов журналирования: ошибочный, предупреждающий, информационный, отладочный и подробный.

Литература: Дэрси JI., Android за 24 часа. Программирование приложений под операционную систему Google/ ДэрсиЛ., КондерШ. — М.: Рид Групп, 2011. — 464 с. — (Профессиональные компьютерные книги). ISBN 978-5-4252-0318-2

По теме:

  • Комментарии