Глава 1. Первое приложение Android Подключение виджетов к программе Теперь, когда кнопкам назначены идентификаторы ресурсов, к ним можно обра- щаться в QuizActivity . Все начинается с добавления двух переменных. Введите следующий код в QuizActivity.java . (Не используйте автозавершение; введите его самостоятельно.) После сохранения файла выводятся два сообщения об ошибках. Листинг 1.8. Добавление полей (QuizActivity.java) public class QuizActivity extends Activity { private Button mTrueButton; private Button mFalseButton; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_quiz); } } Сейчас мы исправим ошибки, а пока обратите внимание на префикс m у имен двух полей (переменных экземпляров). Этот префикс соответствует схеме формирования имен Android, которая будет использоваться в этой книге. Наведите указатель мыши на флаги ошибок слева от кода. Они сообщают об оди- наковой проблеме: « Button не удается связать с типом» (Button cannot be resolved to a type). Чтобы избавиться от ошибок, следует импортировать класс android.widget.Button в QuizActivity.java . Введите следующую директиву импортирования в начале файла: import android.widget.Button; А можно пойти по простому пути и провести организацию импорта. Организация импорта Команда «организации импорта» приказывает среде Eclipse проанализировать код и определить, что потребуется вашей программе из Java и Android SDK. Она импортирует все необходимое и удаляет ранее импортированные классы, которые не используются в программе. Чтобы провести организацию импорта, нажмите: Command+Shift+O на Mac; Ctrl+Shift+O в Windows и Linux. Ошибки должны исчезнуть. (Если они остались, поищите опечатки в коде и XML.) Теперь вы можете подключить свои виджеты-кнопки. Процедура состоит из двух шагов: Назначение слушателей 41 получение ссылок на заполненные объекты View ; назначение для этих объектов слушателей, реагирующих на действия пользо- вателя. Получение ссылок на виджетыВ классе активности можно получить ссылку на заполненный виджет, для чего используется следующий метод Activity : public View findViewById(int id) Метод получает идентификатор ресурса виджета и возвращает объект View В файле QuizActivity.java по идентификаторам ресурсов ваших кнопок можно полу- чить заполненные объекты и присвоить их полям. Учтите, что возвращенный объект View перед присваиванием необходимо преобразовать в Button Листинг 1.9. Получение ссылок на виджеты (QuizActivity.java) public class QuizActivity extends Activity { private Button mTrueButton; private Button mFalseButton; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_quiz); mTrueButton = (Button)findViewById(R.id.true_button); mFalseButton = (Button)findViewById(R.id.false_button); } } Назначение слушателейПриложения Android обычно управляются событиями (event-driven). В отличие от программ командной строки или сценариев, такие приложения запускаются и ожидают наступления некоторого события — например, нажатия кнопки поль- зователем. (События также могут инициироваться ОС или другим приложением, но события, инициируемые пользователем, наиболее очевидны.) Когда ваше приложение ожидает наступления конкретного события, мы говорим, что оно «прослушивает» данное событие. Объект, создаваемый для ответа на событие, называется слушателем (listener). Такой объект реализует интерфейс слушателя данного события. Android SDK поставляется с интерфейсами слушателей для разных событий, по- этому вам не придется писать собственные реализации. В нашем случае прослу- шиваемым событием является «щелчок» на кнопке, поэтому слушатель должен реализовать интерфейс View.OnClickListener 42 Глава 1. Первое приложение Android Начнем с кнопки True . В файле QuizActivity.java включите следующий фрагмент кода в метод onCreate(…) непосредственно после присваивания. Листинг 1.10. Назначение слушателя для кнопки True (QuizActivity.java) @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_quiz); mTrueButton = (Button)findViewById(R.id.true_button); mTrueButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Пока ничего не делает, но скоро будет! } }); mFalseButton = (Button)findViewById(R.id.false_button); } } (Если вы получите ошибку «View cannot be resolved to a type», проведите органи- зацию импорта комбинацией Command+Shift+O или Ctrl+Shift+O для импортирования класса View .) В листинге 1.10 назначается слушатель, информирующий о нажатии виджета But- ton с именем mTrueButton . Метод setOnClickListener(OnClickListener) получает в аргументе слушателя — а конкретнее объект, реализующий OnClickListener Анонимные внутренние классы Слушатель реализован в виде анонимного внутреннего класса. Возможно, син- таксис не очевиден; просто запомните: все, что заключено во внешнюю пару круглых скобок, передается setOnClickListener(OnClickListener) . В круглых скобках создается новый безымянный класс, вся реализация которого передается вызываемому методу. mTrueButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Пока ничего не делает, но скоро будет! } }); Все слушатели в этой книге будут реализованы в виде анонимных внутренних клас- сов. В этом случае реализация методов слушателя находится непосредственно там, где вы хотите ее видеть, а мы избегаем затрат ресурсов на создание именованного класса, который будет использоваться только в одном месте. Так как анонимный класс реализует OnClickListener , он должен реализовать един- ственный метод этого интерфейса onClick(View) . Мы пока оставили реализацию
Уведомления 43 onClick(View) пустой, и компилятор не протестует. Интерфейс слушателя требует, чтобы метод onClick(View) был реализован, но не устанавливает никаких правил относительно того, как именно он будет реализован. (Если ваши знания в области анонимных внутренних классов, слушателей или интерфейсов оставляют желать лучшего, полистайте учебник по Java перед тем, как продолжать, или хотя бы держите справочник под рукой.) Назначьте аналогичного слушателя для кнопки False Листинг 1.11. Назначение слушателя для кнопки False (QuizActivity.java) mTrueButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Пока ничего не делает, но скоро будет! } }); mFalseButton = (Button)findViewById(R.id.false_button); mFalseButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Пока ничего не делает, но скоро будет! } }); } Уведомления Пора заставить кнопки делать что-то полезное. В нашем приложении каждая кноп- ка будет выводить на экран временное уведомление (toast) — короткое сообщение, которое содержит какую-либо информацию для пользователя, но не требует ни ввода, ни действий. Наши уведомления будут сообщать пользователю, правильно ли он ответил на вопрос (рис. 1.12). Для начала вернитесь к файлу strings.xml и добавьте строковые ресурсы, которые будут отображаться в уведомлении. Листинг 1.12. Добавление строк уведомлений (strings.xml)
GeoQuiz Constantinople is the largest city in Turkey. True False Correct! Incorrect! Settings
44 Глава 1. Первое приложение Android Рис. 1.12. Уведомление с информацией для пользователя Уведомление создается вызовом следующего метода класса Toast : public static Toast makeText(Context context, int resId, int duration) Параметр Context обычно содержит экземпляр Activity ( Activity является суб- классом Context ). Во втором параметре передается идентификатор ресурса строки, которая должна выводиться в уведомлении. Параметр Context необходим классу Toast для поиска и использования идентификатора ресурса строки. Третий параметр обычно содержит одну из двух констант Toast , определяющих продолжительность пребывания уведомления на экране. После того как объект уведомления будет создан, вызовите Toast.show() , чтобы уведомление появилось на экране. В классе QuizActivity вызов makeText(…) будет присутствовать в слушателе каж- дой кнопки (листинг 1.13). Вместо того чтобы вводить все вручную, попробуйте добавить эти вызовы с использованием функции автозавершения среды Eclipse. Автозавершение Автозавершение экономит много времени, так что с ним стоит познакомиться по- раньше. Начните вводить новый код из листинга 1.13. Когда вы доберетесь до точки после класса Toast , на экране появляется список методов и констант класса Toast
Выполнение в эмуляторе 45 Чтобы выбрать одну из рекомендаций, нажмите клавишу Tab , чтобы переключиться на подсказку автозавершения. (Если вы не собираетесь использовать автозаверше- ние, просто продолжайте печатать. Без нажатия клавиши Tab или щелчка на окне подсказки подстановка не выполняется.) Выберите в списке рекомендаций метод makeText(Context, int, int) . Механизм автозавершения добавляет вызов метода вместе с заполнителями аргументов. Первый заполнитель выделяется автоматически; введите реальное значение — QuizActivity.this . Затем снова нажмите Tab , чтобы перейти к следующему запол- нителю, и так далее, пока не будет введен весь код из листинга 1.13. Листинг 1.13. Создание уведомлений (QuizActivity.java) mTrueButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(QuizActivity.this, R.string.incorrect_toast, Toast.LENGTH_SHORT).show(); } }); mFalseButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(QuizActivity.this, R.string.correct_toast, Toast.LENGTH_SHORT).show(); } }); В вызове makeText(…) экземпляр QuizActivity передается в аргументе Context . Но как и следовало ожидать, просто передать this нельзя. В этом месте кода мы опре- деляем анонимный класс, где this обозначает View.OnClickListener Благодаря использованию автозавершения вам не придется выполнять организацию импорта, чтобы класс Toast стал доступным. Когда вы соглашаетесь на рекоменда- цию автозавершения, необходимые классы импортируются автоматически. Выполнение в эмуляторе Для запуска приложений Android необходимо устройство — физическое или вир- туальное . Виртуальные устройства работают под управлением эмулятора Android, включенного в поставку средств разработчика. Чтобы создать виртуальное устройство Android (AVD, Android Virtual Device), выполните команду Window Android Virtual Device Manager . Когда на экране появится окно AVD Manager , щелкните на кнопке New... в правой части этого окна. Открывается диалоговое окно с многочисленными параметрами настройки вир- туального устройства. Выберите эмуляцию устройства Galaxy Nexus с Google APIs
46Глава 1. Первое приложение Android (Google Inc.) – API Level 17 , как показано на рис. 1.13. Если вы работаете в системе Windows, возможно, для правильной работы AVD вам придется уменьшить объем памяти ( RAM ) с 1024 до 512. Щелкните на кнопке OK В системе Windows введите 512 вместо 1024 Рис. 1.13. Создание нового виртуального устройства Android Когда виртуальное устройство будет создано, в нем можно запустить приложение GeoQuiz. На панели Package Explorer щелкните правой кнопкой мыши на папке проекта GeoQuiz. В контекстном меню выберите команду Run As Android Application . Eclipse находит созданное виртуальное устройство, устанавливает на нем пакет приложе- ния и запускает приложение. Eclipse может спросить, хотите ли вы использовать автоматический мониторинг с LogCat — соглашайтесь. Возможно, запуск эмулятора потребует некоторого времени, но вскоре при- ложение GeoQuiz запустится на созданном вами виртуальном устройстве. Понажимайте кнопки и оцените уведомления. (Если приложение запускается, когда вас нет поблизости, возможно, вам придется разблокировать AVD после возвращения. AVD работает как настоящее устройство и блокируется после не- которого бездействия.) Для любознательных: процесс построения приложений Android 47 Если при запуске GeoQuiz или нажатии кнопки происходит сбой, в нижней части инструментального окна открывается панель LogCat. Ищите исключения в журнале; они будут выделяться красным цветом. В столбце Text указывается имя исключения и строка, в которой возникла проблема. Рис. 1.14. Исключение NullException в строке 21 Сравните свой код с кодом в книге и попытайтесь найти источник проблемы. Затем снова запустите приложение. Не закрывайте эмулятор; не стоит ждать, пока он загружается, при каждом запуске. Вы можете остановить приложение кнопкой Back (U-образная стрелка), а затем снова запустить приложение из Eclipse, чтобы протестировать изменения. Эмулятор полезен, но тестирование на реальном устройстве дает более точные ре- зультаты. В главе 2 мы запустим приложение GeoQuiz на физическом устройстве, а также расширим набор вопросов по географии. Для любознательных: процесс построения приложений Android Вероятно, у вас уже накопилось неотложных вопросов относительно того, как ра- ботает процесс построения приложений Android. Вы уже видели, что Eclipse строит проект автоматически в процессе его изменения, а не по команде. Во время постро- ения инструментарий Android берет ваши ресурсы, код и файл AndroidManifest.xml (содержащий метаданные приложения) и преобразует их в файл .apk . Полученный файл подписывается отладочным ключом, что позволяет запускать его в эмуляторе. (Чтобы распространять файл .apk среди пользователей, необходимо подписать его ключом публикации. Дополнительную информацию об этом процессе можно найти в документации разработчика Android по адресу https://https://developer. android.com/tools/publishing/preparing.html .) Как содержимое activity_quiz.xml преобразуется в объекты View в приложении? В про- цессе построения утилита aapt (Android Asset Packaging Tool) компилирует ресурсы файлов макетов в более компактный формат. Откомпилированные ресурсы упако- вываются в файл .apk . Затем, когда метод setContentView(…) вызывается в методе onCreate(…) класса QuizActivity , QuizActivity использует класс LayoutInflater для создания экземпляров всех объектов View , определенных в файле макета.
48 Глава 1. Первое приложение Android (Также классы представлений можно создать на программном уровне в классе активности вместо определения их в XML. Однако отделение презентационной логики от логики приложения имеет свои преимущества, главное из которых — ис- пользование изменений конфигурации, встроенное в SDK; мы подробнее поговорим об этом в главе 3.) За дополнительной информацией о том, как работают различные атрибуты XML, и как происходит отображение представлений на экране, обращайтесь к главе 8. Установка и запуск Компиляция кода Java Байт-код Java (.class) Кросс- компиляция для dalvik Байт-код dalvik (.dex) Откомпили- рованные ре- сурсы Построение и подписывание apk Пакет Android (.apk) Рис. 1.15. Построение GeoQuiz
Средства построения программ Android 49 Рис. 1.16. Заполнение activity_quiz.xml Средства построения программ Android Все программы, которые мы запускали до настоящего времени, исполнялись из среды Eclipse. Этот процесс интегрирован в используемый плагин ADT — он вы- зывает стандартные средства построения программ Android (такие, как aapt), но сам процесс построения проходит под управлением Eclipse. Может оказаться, что вам по каким-то своим причинам потребуется провести по- строение за пределами среды Eclipse. Для этого проще всего воспользоваться про- граммой командной строки. Две самых популярных утилиты такого рода — maven и ant. Ant уступает по функциональности, но намного проще в использовании. Прежде всего выполните два шага: Убедитесь в том, что программа ant установлена и ее можно запустить. Убедитесь в том, что папки tools/ и platform-tools/ в Android SDK включены в пути поиска исполняемых файлов. Теперь перейдите в каталог проекта и выполните следующую команду: $ android update project -p .
50 Глава 1. Первое приложение Android Шаблон генератора проектов Eclipse не включает файл build.xml для ant. Первая ко- манда генерирует файл build.xml за вас; вам остается лишь выполнить ее во второй раз. Постройте проект. Чтобы построить и подписать отладочный файл .apk , выполните следующую команду в той же папке: $ ant debug Эта команда непосредственно строит программу. Она создает файл .apk , находя- щийся в папке bin/ имя-проекта - debug.apk . Когда файл .apk будет создан, установите его следующей командой: $ adb install bin/имя-проекта-debug.apk Команда устанавливает приложение на подключенное устройство, но не запускает его — вы должны сделать это вручную.
Android и MVC В этой главе мы обновим приложение GeoQuiz и включим в него дополнительные вопросы. Рис. 2.1. Больше вопросов! Для этого в проект GeoQuiz будет добавлен класс с именем TrueFalse . Экземпляр этого класса инкапсулирует один вопрос с ответом «да/нет». Затем мы создадим массив объектов TrueFalse , с которым будет работать класс QuizActivity 2
| Образовательный портал
Как узнать результаты егэ
Стихи про летний лагерь
3агадки для детей |