Android – базирующаяся на ОС Linux операционная система с открытым исходным кодом, предназначенная для мобильных устройств – таких, как, например, смартфоны или планшетные компьютеры.
Это руководство предназначено для введения в основные понятия программирования под Android, так что после его изучения вы будете понимать некоторые базовые концепции программирования под эту ОС.
От вас же, в свою очередь, требуется только желание и базовое понимание программирования на языке Java. Не так много, правда? Что ж, начнём!
Среда разработки
Для разработки приложений под Android можно использовать любые из перечисленных операционных систем:
- Microsoft Windows XP или более поздняя версия
- Mac OS X 10.5.8 или более поздняя версия с чипом Intel
- Linux, включающая GNU C Library 2.7 или более позднюю версию
При этом все необходимые инструменты для разработки Android-приложений находятся в свободном доступе и вы можете загрузить их из Интернета. Для того, чтобы начать создавать приложения под Android, вам понадобятся:
- Java JDK5 или более поздняя версия
- Android Studio
Структура приложений
Поздравляем, ваше оборудование готово к работе! Однако прежде чем приступить к вашему первому приложению, поговорим о том, что из себя представляет приложение на Android и из чего оно состоит.
Компоненты приложения являются своего рода «строительными блоками» для приложения Android. Эти компоненты связаны файлом-манифестом приложения AndroidManifest.xml, который описывает каждый компонент приложения и взаимодействие этих компонентов между собой.
Есть четыре базовых типа компонентов, которые могут быть использованы в приложении Android:
- Операции (Activities) представляют собой элементы пользовательского интерфейса (одна операция – один экран) и отвечают за взаимодействие пользователя с экраном мобильного устройства;
- Службы (Services) представляют собой длительные операции, работающие в фоновом режиме и не имеющие пользовательского интерфейса (например, передача данных), вместо этого они, как правило, запускаются иными элементами, уже имеющими пользовательский интерфейс, и взаимодействуют с ними;
- Приемники широковещательных сообщений (Broadcast receivers) представляют собой компоненты, реагирующие на объявления самой ОС, передаваемые всей системе (как хороший пример – объявление о низком уровне заряда батареи устройства). Они также не имеют пользовательского интерфейса, однако могут передавать данные другим компонентам, где они демонстрируются пользователю в виде уведомлений;
- Поставщики контента (Content providers) представляют собой компоненты, управляющие взаимодействием приложения с его базой данных — посредством поставщика контента другие компоненты приложения могут запрашивать или изменять данные.
Помимо четырех базовых типов, существуют дополнительные типы компонентов, используемые для выстраивания взаимодействий и связей как между базовыми типами компонентов, так и между компонентами и внешними элементами. К ним относятся:
- Фрагменты (Fragments) – части пользовательского интерфейса в Операциях (см. выше);
- Виды (Views) – элементы пользовательского интерфейса, отображаемые на экране, например, кнопки, списки и т. д.;
- Макеты (Layouts) – определяют элементы пользовательского интерфейса, их свойства и расположение;
- Намерения (Intents) – соединяют вместе различные компоненты приложения или связывают друг с другом работу разных приложений;
- Ресурсы (Resources) – внешние элементы, такие, как строки, константы или изображения;
- Манифест (Manifest) – конфигурационный файл приложения.
Теперь, когда вы получили базовое понимание о структуре приложений на Android, хотелось бы предложить вам самим попробовать создать свое первое приложение.
Первое приложение
Итак, давайте приступим к созданию простого Android-приложения, которое будет выводить на экран «Hello World!».
У вас к этому времени уже должен быть установлен Android Studio последней версии. Ниже будет приведена небольшая пошаговая инструкция:
- Откройте Android Studio.
- В открывшемся окне кликните на «Start a new Android Studio project», чтобы создать новый проект.
- В открывшемся окне в строку «Application name» введите название вашего будущего приложения. Нажмите Next.
- В следующем окне вам нужно выбрать тип устройств, для которых создается приложение – в нашем случае необходимо выбрать «Phone and Tablet» (смартфоны и планшетные компьютеры), а в выпадающем списке под названием «Minimum SDK» нужно выбрать версию Android, для которой создается приложение (обычно указывается самая ранняя версия, способная запустить приложение) – в нашем конкретном случае выберем версию Android 6.0. Если в вашей версии есть возможность выбрать язык программирования (выпадающее окно Language), выберите пункт “Java”. Остальные опции можно оставить без изменений. Нажмите Next.
- На следующем этапе выберите пункт Empty Activity – это будет означать, что экран нашего приложения не будет иметь никаких дополнительных элементов. Нажмите Next.
Теперь перед вами открылась привычная среда разработки. К сожалению или к счастью, но сейчас вам не нужно будет писать код – среда разработки уже сделала это за вас, создав файлы для приложения, выводящего «Hello world!» на экран, по умолчанию. Вместо этого хотелось бы обратить ваше внимание на несколько созданных файлов и папок, найти которые вы можете в колонке слева, отображающей все элементы проекта.
- Файл MainActivity.java
В папке «Java» содержатся исходные файлы формата .java для вашего приложения. По умолчанию в ней находится исходный файл MainActivity.java, имеющий класс Операция – он запускается при нажатии пользователем на иконку приложения на устройстве. Этот файл содержит главный код приложения, и именно он преобразуется в файл .exe для запуска приложения на устройстве.
- Файл AndroidManifest.xml
Это файл типа «Манифест», который описывает основные характеристики приложения и определяет каждый из его компонентов. Он является своего рода интерфейсом между ОС Android и вашим приложением – если компонент не упомянут в этом файле, он не будет отображен и в операционной системе.
- Файл Build.gradle
Это автоматически генерируемый файл, содержащий определённые данные касательно приложения – такие, как, например, версия SDK.
Запустить приложение можно двумя способами: на реальном устройстве или на эмуляторе в самой среде разработки. В нашем случае мы рассмотрим более универсальный случай – запуск на эмуляторе, полностью имитирующем работу устройства с операционной системой Android.
Запуск приложения на эмуляторе
Попытайтесь запустить приложение кнопкой «Run» – в появившемся диалоговом окне выберите пункт «Create New Virtual Device». В последующих окнах нужно будет выбрать размер экрана и версию Android – помните, что она должна быть не ниже, чем указанная на этапе создания проекта. В случае, если данная версия Android будет отсутствовать на компьютере, Android Studio предложит ее загрузить. Остальные пункты можно оставить без изменений – на данный момент нет необходимости их изменять. После выбора всех настроек нажмите кнопку «Finish», и если вы увидели на своем мониторе экран телефона с названием вашего приложения сверху и с надписью «Hello world!» на экране, значит, вы можете себя поздравить – вы создали свое первое Android-приложение!
Теперь у вас есть базовое понимание и минимальный опыт в создании приложений на Android. Этого, разумеется, совершенно не хватит, чтобы заниматься разработкой, но это необходимый для дальнейшего развития фундамент – продолжайте изучать и практиковаться! Всего наилучшего!
Также можно научиться создавать приложения на Android и другие ОС после прохождения нашего шестимесячного курса «Профессия: Разработчик» 👉 Узнать подробности!
Урок 1. Введение.
Урок 2. Установка Android Studio
Урок 3. Создание AVD. Первое приложение. Структура Android-проекта.
Урок 4. Компоненты экрана и их свойства
Урок 5. Layout-файл в Activity. XML представление. Смена ориентации экрана.
Урок 6. Виды Layouts. Ключевые отличия и свойства.
Урок 7. Layout параметры для View-элементов.
Урок 8. Работаем с элементами экрана из кода
Урок 9. Обработчики событий на примере Button.
Урок 10. Оптимизируем реализацию обработчиков.
Урок 11. Папка res/values. Используем ресурсы приложения.
Урок 12. Логи и всплывающие сообщения
Урок 13. Создание простого меню
Урок 14. Меню, группы, порядок. MenuInflater и xml-меню.
Урок 15. Контекстное меню
Урок 16. Программное создание экрана. LayoutParams
Урок 17. Создание View-компонент в рабочем приложении
Урок 18. Меняем layoutParams в рабочем приложении
Урок 19. Пишем простой калькулятор
Урок 20. Анимация
Урок 21. Создание и вызов Activity
Урок 22. Intent, Intent Filter, Context — теория
Урок 23. Activity Lifecycle. В каких состояниях может быть Activity
Урок 24. Activity Lifecycle, пример смены состояний с двумя Activity
Урок 25. Task. Что это такое и как формируется
Урок 26. Intent Filter — практика
Урок 27. Читаем action из Intent
Урок 28. Extras — передаем данные с помощью Intent
Урок 29. Вызываем Activity и получаем результат. Метод startActivityForResult
Урок 30. Подробнее про onActivityResult. Зачем нужны requestCode и resultCode
Урок 31. Зачем у Intent есть атрибут data. Что такое Uri. Вызываем системные приложения
Урок 32. Пишем простой браузер
Урок 33. Хранение данных. Preferences.
Урок 34. Хранение данных. SQLite
Урок 35. SQLite. Методы update и delete с указанием условия
Урок 36. SQLite. Подробнее про метод query. Условие, сортировка, группировка
Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLite. Метод rawQuery.
Урок 38. Транзакции в SQLite. Небольшой FAQ по SQLite.
Урок 39. onUpgrade. Обновляем БД в SQLite
Урок 40. LayoutInflater. Учимся использовать.
Урок 41. Используем LayoutInflater для создания списка
Урок 42. Список — ListView
Урок 43. Одиночный и множественный выбор в ListView
Урок 44. События в ListView
Урок 45. Список-дерево ExpandableListView
Урок 46. События ExpandableListView
Урок 47. Обзор адаптеров
Урок 48. Используем SimpleAdapter.
Урок 49. SimpleAdapter. Методы SetViewText и SetViewImage
Урок 50. SimpleAdapter. Используем ViewBinder
Урок 51. SimpleAdapter, добавление и удаление записей
Урок 52. SimpleCursorAdapter, пример использования
Урок 53. SimpleCursorTreeAdapter, пример использования
Урок 54. Кастомизация списка. Создаем свой адаптер
Урок 55. Header и Footer в списках. HeaderViewListAdapter
Урок 56. Spinner – выпадающий список
Урок 57. GridView и его атрибуты
Урок 58. Диалоги. TimePickerDialog
Урок 59. Диалоги. DatePickerDialog
Урок 60. Диалоги. AlertDialog: Title, Message, Icon, Buttons
Урок 61. Диалоги. AlertDialog.Метод onPrepareDialog
Урок 62. Диалоги. AlertDialog. Список
Урок 63. Диалоги. AlertDialog. Список с одиночным выбором
Урок 64. Диалоги. AlertDialog. Список с множественным выбором
Урок 65. Диалоги. AlertDialog. Кастомизация
Урок 66. Диалоги. Обработчики и операции
Урок 67. Диалоги. ProgressDialog
Урок 68. Немного о Parcel
Урок 69. Передаем Parcelable объекты с помощью Intent
Урок 70. onSaveInstanceState. Сохранение данных Activity при повороте экрана
Урок 71. Preferences как настройки приложения. PreferenceActivity
Урок 72. Preferences. Список, экраны и категории
Урок 73. Preferences. Управляем активностью настроек (setEnabled)
Урок 74. Preferences. Программное создание экрана настроек
Урок 75. Хранение данных. Работа с файлами.
Урок 76. Tab — вкладки. Общий обзор
Урок 77. Tab — вкладки. TabActivity. Activity, как содержимое вкладки
Урок 78. Tab — вкладки. TabContentFactory, ручное создание содержимого вкладки
Урок 79. XmlPullParser. Парсим XML
Урок 80. Handler. Немного теории. Наглядный пример использования
Урок 81. Handler. Посылаем простое сообщение
Урок 82. Handler. Пример с более содержательными сообщениями
Урок 83. Handler. Отложенные сообщения, удаление из очереди, Handler.Callback
Урок 84. Handler. Обработка Runnable
Урок 85. Еще несколько способов выполнения кода в UI-потоке
Урок 86. AsyncTask. Знакомство, несложный пример
Урок 87. AsyncTask. Параметры. Промежуточные результаты
Урок 88. AsyncTask. Итоговый результат. Метод get
Урок 89. AsyncTask. Cancel – отменяем задачу в процессе выполнения
Урок 90. AsyncTask. Status – статусы задачи
Урок 91. AsyncTask. Поворот экрана
Урок 92. Service. Простой пример
Урок 93. Service. Передача данных в сервис. Методы остановки сервиса
Урок 94. Service. Подробно про onStartCommand
Урок 95. Service. Обратная связь с помощью PendingIntent
Урок 96. Service. Обратная связь с помощью BroadcastReceiver
Урок 97. Service. Биндинг. ServiceConnection
Урок 98. Service. Локальный биндинг
Урок 99. Service. Уведомления — notifications
Урок 100. Service. IntentService. Foreground. Автозагрузка сервиса
Урок 101. Создаем свой ContentProvider
Урок 102. Touch – обработка касания
Урок 103. MultiTouch – обработка множественных касаний
Урок 104. Android 3. Fragments. Lifecycle
Урок 105. Android 3. Fragments. Динамическая работа
Урок 106. Android 3. Fragments. Взаимодействие с Activity
Урок 107. Android 3. ActionBar. Размещение элементов
Урок 108. Android 3. ActionBar. Навигация — табы и выпадающий список
Урок 109. Android 3. Fragments. ListFragment — список
Урок 110. Android 3. Fragments. DialogFragment — диалог
Урок 111. Android 3. Fragments. PreferenceFragment — настройки. Headers
Урок 112. Android 3. ActionBar. Динамическое размещение элементов
Урок 113. Android 3. ActionMode, как альтернатива контекстному меню
Урок 114. Android 3. Библиотека Support Library. Зачем нужна и как ее использовать на примере фрагментов
Урок 115. Одно приложение на разных экранах
Урок 116. Поведение Activity в Task. Intent-флаги, launchMode, affinity
Урок 117. Виджеты. Создание. Lifecycle
Урок 118. Виджеты. Конфигурационный экран. Обновление
Урок 119. PendingIntent – флаги, requestCode. AlarmManager
Урок 120. Виджеты. Обработка нажатий
Урок 121. Виджеты. Список
Урок 122. Виджеты. Превью, изменение размера, экран блокировки, ручное обновление
Урок 123. Как подписать приложение. Утилиты keytool и jarsigner
Урок 124. Что такое Package для приложения
Урок 125. ViewPager
Урок 126. Медиа. MediaPlayer – аудио/видео плеер, основные возможности
Урок 127. Медиа. SoundPool
Урок 128. Медиа. Audio Focus
Урок 129. Медиа. Запись звука с помощью MediaRecorder
Урок 130. Медиа. Запись звука с помощью AudioRecorder
Урок 131. Камера. Используем системное приложение
Урок 132. Камера. Вывод изображения на экран. Размер preview. Обработка поворота устройства
Урок 133. Камера. Делаем снимок и пишем видео
Урок 134. Камера. Настройки
Урок 135. Loader. LoaderManager. AsyncTaskLoader
Урок 136. CursorLoader
Урок 137. Сенсоры. Ускорение, ориентация.
Урок 138. Определение местоположения. GPS координаты.
Урок 139. Google maps. Создание и настройка проекта. Карта, камера, события
Урок 140. Google maps. Свои объекты на карте
Урок 141. Рисование. Доступ к Canvas
Урок 142. Рисование. Простые фигуры, текст
Урок 143. Рисование. Path
Урок 144. Рисование. Matrix-преобразования
Урок 145. Рисование. Matrix. setRectToRect и setPolyToPoly
Урок 146. Рисование. Canvas-преобразования. Методы save и restore.
Урок 147. Рисование. Region
Урок 148. Рисование. Canvas, clip
Урок 149. Рисование. Текст
Урок 150. Рисование. PathMeasure – информация о Path-объекте
Урок 151. Рисование. PathEffect
Урок 152. Рисование. Picture
Урок 153. Рисование. ColorFilter, ColorMatrix
Урок 154. Рисование. PorterDuff.Mode, PorterDuffXfermode
Урок 155. Рисование. PorterDuffColorFilter
Урок 156. Рисование. AvoidXfermode
Урок 157. Рисование. Bitmap. BitmapFactory. Чтение, вывод на канву, основная информация
Урок 158. Рисование. Bitmap. Методы createBitmap, работа с пикселами, density, mutable
Урок 159. Рисование. Bitmap. BitmapFactory.Options, сохранение в файл
Урок 160. Рисование. Bitmap. Чтение изображений большого размера
Урок 161. Рисование. Bitmap. Memory-кэш. Picasso
Урок 162. Графика. Drawable. Shape, Gradient.
Урок 163. Графика. Drawable. Bitmap, Layer List, State List.
Урок 164. Графика. Drawable. Level List, Transition, Inset, Clip, Scale
Урок 165. Графика. BitmapShader, LinearGradient, RadialGradient, SweepGradient
Урок 166. Графика. Создание своего Drawable
Урок 167. Рисование. Метод Canvas saveLayer.
Урок 168. OpenGL. Введение.
Урок 169. OpenGL. Шейдеры
Урок 170. OpenGL. Графические примитивы
Урок 171. OpenGL. Цвет.
Урок 172. OpenGL. Perspective. Frustum. Ortho.
Урок 173. OpenGL. Камера
Урок 174. OpenGL. Модель
Урок 175. OpenGL. Текстуры.
Урок 176. OpenGL. Индексы, текстуры для куба.
Урок 180. ConstraintLayout. Основы
Урок 181. ConstraintLayout: match_constraints, инструменты в toolbar, guidelines, aspect ratio
Урок 182. ConstraintLayout: chain, weight, barrier, group, circular
Урок 183. ConstraintSet. Программная настройка ConstraintLayout
Урок 184. Android Notifications. Уведомления. Основы
Урок 185. Notifications. Режимы открытия Activity
Урок 186. Notifications. Расширенные уведомления
Урок 187. Notifications. Action кнопки. Reply.
Урок 188. Notifications. Кастомные уведомления
Урок 189. Notifications. Группировка уведомлений
Урок 190. Notifications. Каналы
#Руководства
-
0
Платформа Android открытая, поэтому каждый может написать своё приложение и распространять его через каталоги программ. Все инструменты бесплатны.
vlada_maestro / shutterstock
Пишет про разработку в Skillbox Media. Работал главным редактором сайта «Хабрахабр», ведёт корпоративные блоги.
Язык программирования для мобильной разработки на Android очень простой — это Java. Сейчас Google активно продвигает Kotlin как язык, который сможет заменить Java. Приложения пишут и на C++.
Создание простейшего приложения состоит из нескольких этапов:
- проект в Android Studio;
- создание пользовательского интерфейса;
- добавление активностей, навигации и действий;
- тест-драйв приложения в эмуляторе.
Первым делом установите программу Android Studio. Это официальная среда разработки (IDE) для Android, она работает на Windows, macOS и Linux. Хотя при разработке программ для Android можно использовать и другие среды, кроме Android Studio.
Если на компьютере не установлены Android SDK и другие компоненты, то Android Studio автоматически скачает их. Android SDK — это среда программирования, в которую входят библиотеки, исполняемые файлы, скрипты, документация и т.д.
Android SDK компилирует код вместе с любыми данными и ресурсами в файл с расширением .apk. Он содержит всё необходимое для установки приложения на Android-устройство.
Полезно установить и эмулятор Android, чтобы запускать и тестировать приложения. Эмулятор поставляется в комплекте с Android Studio.
Когда все инструменты установлены, можно создать первый проект. Но сначала нужно разобраться с основными понятиями.
Android-приложение состоит из четырёх компонентов. Каждый компонент — это точка входа, через которую система или пользователь может получить доступ.
- Активность (activity) — элементы интерактивного пользовательского интерфейса.
Одна активность задействует другую и передаёт информацию о том, что намерен делать пользователь, через класс Intent (намерения). Активности подобны веб-страницам, а намерения — ссылкам между ними. Запуск приложения — это активность Main. - Сервис (service) — универсальная точка входа для поддержания работы приложения в фоновом режиме.
Этот компонент выполняет длительные операции или работу для удалённых процессов без визуального интерфейса. - Широковещательный приемник (broadcast receiver) транслирует нескольким участникам намерения из приложения.
- Поставщик содержимого (content provider) управляет общим набором данных приложения из файловой системы, базы данных SQLite, интернета или другого хранилища.
Теперь попробуем сделать своё приложение для Android.
Выбираем название приложения, домен компании, путь к проекту и название пакета. Указываем, включить ли поддержку опциональных языков программирования C++ и Kotlin.
Задаём одну или несколько целевых платформ для сборки. Для этого используется SDK и AVD, менеджер виртуальных устройств Android. Инструмент позволяет устанавливать в SDK пакеты, которые поддерживают несколько версий ОС Android и несколько уровней API (интерфейсов программирования приложений).
Справка
Чем ниже версия Android, тем больше устройств, на которых приложение запустится. Чем выше версия, тем богаче функциональность API.
Выбираем основную активность, которая будет запускаться при нажатии на иконку приложения, и даём ей имя.
После нескольких минут сборки Android Studio открывает интерфейс IDE. Здесь три основных момента.
Если выбрать в выпадающем меню вид Android, то вы увидите файлы проекта. Например, наша основная активность называется app > java > ru.skillbox.skillboxapp > FullscreenActivity. При создании проекта мы указали вместо активности Main полноэкранную активность.
Далее можно посмотреть файл app > res > layout > activity_fullscreen.xml. Это XML-файл с макетом для UI нашей основной активности.
Наконец, третий важный файл app > manifests > AndroidManifest.xml описывает фундаментальные характеристики приложения и определяет все его компоненты.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ru.skillbox.skillboxapp">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".FullscreenActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name"
android:theme="@style/FullscreenTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Созданное нами приложение — это одна активность, которая запускается в полноэкранном режиме и не имеет графических элементов.
Запускаем на Android-устройстве или в эмуляторе.
Смартфон или планшет для этого подключаем в режиме USB-отладки, которая активируется в Настройках разработчика в меню Настройки.
Для запуска в эмуляторе нажимаем в Android Studio кнопку Run в меню Run (Shift+F10). Выбираем подходящее устройство и версию ОС, портретную или ландшафтную (альбомную) ориентацию.
Пользовательский интерфейс Android-приложения создаётся через иерархию макетов (layouts, объекты ViewGroup) и виджетов (объекты View). Макеты управляют расположением дочерних виджетов на экране. Сами виджеты — это непосредственно компоненты UI: кнопки, текстовые поля на экране и т.п.
Интерфейс активностей создаётся в Android Studio в редакторе макетов (Layout Editor) и хранится по большей части в XML-файлах.
- Открываем файл app > res > layout > activity_fullscreen.xml.
- Добавляем на экран из палитры (Palette) виджеты перетаскиванием мышью.
- Например, берём текстовое поле (PlainText). Это виджет EditText, куда пользователь может вводить текст.
- Добавляем кнопки и другие нужные элементы.
Предположим, мы создали активность с текстовым полем и кнопкой «Отправить». После этого нужно написать, что конкретно будет происходить при нажатии кнопки «Отправить».
- Заходим в код app > java > FullscreenActivity.
- Добавляем метод SendMessage() в класс FullscreenActivity, чтобы при нажатии на кнопку вызывался этот метод.
- Создаём намерения (класс Intent) для перехода от одной активности к другой, новые активности, навигацию и всё остальное, что необходимо для приложения.
И, конечно, начинаем мечтать, как монетизировать приложение.
Как зарабатывать больше с помощью нейросетей?
Бесплатный вебинар: 15 экспертов, 7 топ-нейросетей. Научитесь использовать ИИ в своей работе и увеличьте доход.
Узнать больше
Время на прочтение
8 мин
Количество просмотров 540K
В любом деле самое сложное — это начало. Часто бывает тяжело войти в контекст, с чем столкнулся и я, решив разработать свое первое Android-приложение. Настоящая статья для тех, кто хочет начать, но не знает с чего.
Статья затронет весь цикл разработки приложения. Вместе мы напишем простенькую игру “Крестики-Нолики” с одним экраном (в ОС Android это называется Activity).
Отсутствие опыта разработки на языке Java не должно стать препятствием в освоении Android. Так, в примерах не будут использоваться специфичные для Java конструкции (или они будет минимизированы на столько, на сколько это возможно). Если Вы пишете, например, на PHP и знакомы с основополагающими принципами в разработке ПО, эта статья будет вам наиболее полезна. В свою очередь так как, я не являюсь экспертом по разработке на Java, можно предположить, что исходный код не претендует на лейбл “лучшие практики разработки на Java”.
Установка необходимых программ и утилит
Перечислю необходимые инструменты. Их 3:
- JDK — набор для разработки на языке Java;
- Android SDK and AVD Manager — набор утилит для разработки + эмулятор;
- IDE c поддержкой разработки для Android:
- Eclipse + ADT plugin;
- IntelliJ IDEA Community Edition;
- Netbeans + nbandroid plugin;
Утилиты устанавливаются в определенном выше порядке. Ставить все перечисленные IDE смысла нет (разве только если Вы испытываете затруднения с выбором подходящей). Я использую IntelliJ IDEA Community Edition, одну из самых развитых на данный момент IDE для Java.
Запуск виртуального устройства
Запустив AVD Manager и установив дополнительные пакеты (SDK различных версий), можно приступить к созданию виртуального устройства с необходимыми параметрами. Разобраться в интерфейсе не должно составить труда.
Список устройств
Создание проекта
Мне всегда не терпится приступить к работе, минимизируя подготовительные мероприятия, к которым относится создание проекта в IDE, особенно, когда проект учебный и на продакшн не претендует.
Итак, File->New Project:
По нажатию кнопки F6 проект соберется, откомпилируется и запустится на виртуальном девайсе.
Структура проекта
На предыдущем скриншоте видна структура проекта. Так как в этой статье мы преследуем сугубо практические цели, заострим внимание лишь на тех папках, которые будем использовать в процессе работы. Это следующие каталоги: gen, res и src.
В папке gen находятся файлы, которые генерируются автоматически при сборке проекта. Вручную их менять нельзя.
Папка res предназначена для хранения ресурсов, таких как картинки, тексты (в том числе переводы), значения по-умолчанию, макеты (layouts).
src — это папка в которой будет происходить основная часть работы, ибо тут хранятся файлы с исходными текстами нашей программы.
Первые строки
Как только создается Activity (экран приложения), вызывается метод onCreate(). IDE заполнила его 2 строчками:
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Метод setContentView (равносильно this.setContentView) устанавливает xml-макет для текущего экрана. Далее xml-макеты будем называть «layout», а экраны — «Activity». Layout в приложении будет следующий:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/main_l"
android:gravity="center"
>
</TableLayout>
Для этого приложения идеально подойдет TableLayout. Id можно присвоить любому ресурсу. В данном случае, TableLayout присвоен id = main_l. При помощи метода findViewById() можно получить доступ к виду:
private TableLayout layout; // это свойство класса KrestikinolikiActivity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
layout = (TableLayout) findViewById(R.id.main_l);
buildGameField();
}
Теперь необходимо реализовать метод buildGameField(). Для этого требуется сгенерировать поле в виде матрицы. Этим будет заниматься класс Game. Сначала нужно создать класс Square для ячеек и класс Player, объекты которого будут заполнять эти ячейки.
Square.java
package com.example;
public class Square {
private Player player = null;
public void fill(Player player) {
this.player = player;
}
public boolean isFilled() {
if (player != null) {
return true;
}
return false;
}
public Player getPlayer() {
return player;
}
}
Player.java
package com.example;
public class Player {
private String name;
public Player(String name) {
this.name = name;
}
public CharSequence getName() {
return (CharSequence) name;
}
}
Все классы нашего приложения находятся в папке src.
Game.java
package com.example;
public class Game {
/**
* поле
*/
private Square[][] field;
/**
* Конструктор
*
*/
public Game() {
field = new Square[3][3];
squareCount = 0;
// заполнение поля
for (int i = 0, l = field.length; i < l; i++) {
for (int j = 0, l2 = field[i].length; j < l2; j++) {
field[i][j] = new Square();
squareCount++;
}
}
}
public Square[][] getField() {
return field;
}
}
Инициализация Game в конструкторе KrestikinolikiActivity.
public KrestikinolikiActivity() {
game = new Game();
game.start(); // будет реализован позже
}
Метод buildGameField() класса KrestikinolikiActivity. Он динамически добавляет строки и колонки в таблицу (игровое поле):
private Button[][] buttons = new Button[3][3];
//(....)
private void buildGameField() {
Square[][] field = game.getField();
for (int i = 0, lenI = field.length; i < lenI; i++ ) {
TableRow row = new TableRow(this); // создание строки таблицы
for (int j = 0, lenJ = field[i].length; j < lenJ; j++) {
Button button = new Button(this);
buttons[i][j] = button;
button.setOnClickListener(new Listener(i, j)); // установка слушателя, реагирующего на клик по кнопке
row.addView(button, new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT)); // добавление кнопки в строку таблицы
button.setWidth(107);
button.setHeight(107);
}
layout.addView(row, new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT,
TableLayout.LayoutParams.WRAP_CONTENT)); // добавление строки в таблицу
}
}
В строке 8 создается объект, реализующий интерфейс View.OnClickListener. Создадим вложенный класс Listener. Он будет виден только из KrestikinolikiActivity.
public class Listener implements View.OnClickListener {
private int x = 0;
private int y = 0;
public Listener(int x, int y) {
this.x = x;
this.y = y;
}
public void onClick(View view) {
Button button = (Button) view;
}
}
Осталось реализовать логику игры.
public class Game {
/**
* игроки
*/
private Player[] players;
/**
* поле
*/
private Square[][] field;
/**
* начата ли игра?
*/
private boolean started;
/**
* текущий игрок
*/
private Player activePlayer;
/**
* Считает колличество заполненных ячеек
*/
private int filled;
/**
* Всего ячеек
*/
private int squareCount;
/**
* Конструктор
*
*/
public Game() {
field = new Square[3][3];
squareCount = 0;
// заполнение поля
for (int i = 0, l = field.length; i < l; i++) {
for (int j = 0, l2 = field[i].length; j < l2; j++) {
field[i][j] = new Square();
squareCount++;
}
}
players = new Player[2];
started = false;
activePlayer = null;
filled = 0;
}
public void start() {
resetPlayers();
started = true;
}
private void resetPlayers() {
players[0] = new Player("X");
players[1] = new Player("O");
setCurrentActivePlayer(players[0]);
}
public Square[][] getField() {
return field;
}
private void setCurrentActivePlayer(Player player) {
activePlayer = player;
}
public boolean makeTurn(int x, int y) {
if (field[x][y].isFilled()) {
return false;
}
field[x][y].fill(getCurrentActivePlayer());
filled++;
switchPlayers();
return true;
}
private void switchPlayers() {
activePlayer = (activePlayer == players[0]) ? players[1] : players[0];
}
public Player getCurrentActivePlayer() {
return activePlayer;
}
public boolean isFieldFilled() {
return squareCount == filled;
}
public void reset() {
resetField();
resetPlayers();
}
private void resetField() {
for (int i = 0, l = field.length; i < l; i++) {
for (int j = 0, l2 = field[i].length; j < l2; j++) {
field[i][j].fill(null);
}
}
filled = 0;
}
}
Определение победителя
К. О. подсказывает, что в крестики-нолики выирывает тот, кто выстроет X или O в линию длиной, равной длине поля по-вертикали, или по-горизонтали, или по-диагонали. Первая мысль, которая приходит в голову — это написать методы для каждого случая. Думаю, в этом случае хорошо подойдет паттерн Chain of Responsobility. Определим интерфейс
package com.example;
public interface WinnerCheckerInterface {
public Player checkWinner();
}
Так как Game наделен обязанностью выявлять победителя, он реализует этот интерфейс. Настало время создать виртуальных «лайнсменов», каждый из которых будет проверять свою сторону. Все они реализует интерфейс WinnerCheckerInterface.
WinnerCheckerHorizontal.java
package com.example;
public class WinnerCheckerHorizontal implements WinnerCheckerInterface {
private Game game;
public WinnerCheckerHorizontal(Game game) {
this.game = game;
}
public Player checkWinner() {
Square[][] field = game.getField();
Player currPlayer;
Player lastPlayer = null;
for (int i = 0, len = field.length; i < len; i++) {
lastPlayer = null;
int successCounter = 1;
for (int j = 0, len2 = field[i].length; j < len2; j++) {
currPlayer = field[i][j].getPlayer();
if (currPlayer == lastPlayer && (currPlayer != null && lastPlayer !=null)) {
successCounter++;
if (successCounter == len2) {
return currPlayer;
}
}
lastPlayer = currPlayer;
}
}
return null;
}
}
WinnerCheckerVertical.java
package com.example;
public class WinnerCheckerVertical implements WinnerCheckerInterface {
private Game game;
public WinnerCheckerVertical (Game game) {
this.game = game;
}
public Player checkWinner() {
Square[][] field = game.getField();
Player currPlayer;
Player lastPlayer = null;
for (int i = 0, len = field.length; i < len; i++) {
lastPlayer = null;
int successCounter = 1;
for (int j = 0, len2 = field[i].length; j < len2; j++) {
currPlayer = field[j][i].getPlayer();
if (currPlayer == lastPlayer && (currPlayer != null && lastPlayer !=null)) {
successCounter++;
if (successCounter == len2) {
return currPlayer;
}
}
lastPlayer = currPlayer;
}
}
return null;
}
}
WinnerCheckerDiagonalLeft.java
package com.example;
public class WinnerCheckerDiagonalLeft implements WinnerCheckerInterface {
private Game game;
public WinnerCheckerDiagonalLeft(Game game) {
this.game = game;
}
public Player checkWinner() {
Square[][] field = game.getField();
Player currPlayer;
Player lastPlayer = null;
int successCounter = 1;
for (int i = 0, len = field.length; i < len; i++) {
currPlayer = field[i][i].getPlayer();
if (currPlayer != null) {
if (lastPlayer == currPlayer) {
successCounter++;
if (successCounter == len) {
return currPlayer;
}
}
}
lastPlayer = currPlayer;
}
return null;
}
}
WinnerCheckerDiagonalRight.java
package com.example;
public class WinnerCheckerDiagonalRight implements WinnerCheckerInterface {
private Game game;
public WinnerCheckerDiagonalRight(Game game) {
this.game = game;
}
public Player checkWinner() {
Square[][] field = game.getField();
Player currPlayer;
Player lastPlayer = null;
int successCounter = 1;
for (int i = 0, len = field.length; i < len; i++) {
currPlayer = field[i][len - (i + 1)].getPlayer();
if (currPlayer != null) {
if (lastPlayer == currPlayer) {
successCounter++;
if (successCounter == len) {
return currPlayer;
}
}
}
lastPlayer = currPlayer;
}
return null;
}
}
Проинициализируем их в конструкторе Game:
//(....)
/**
* "Судьи" =). После каждого хода они будут проверять,
* нет ли победителя
*/
private WinnerCheckerInterface[] winnerCheckers;
//(....)
public Game() {
//(....)
winnerCheckers = new WinnerCheckerInterface[4];
winnerCheckers[0] = new WinnerCheckerHorizontal(this);
winnerCheckers[1] = new WinnerCheckerVertical(this);
winnerCheckers[2] = new WinnerCheckerDiagonalLeft(this);
winnerCheckers[3] = new WinnerCheckerDiagonalRight(this);
//(....)
}
Реализация checkWinner():
public Player checkWinner() {
for (WinnerCheckerInterface winChecker : winnerCheckers) {
Player winner = winChecker.checkWinner();
if (winner != null) {
return winner;
}
}
return null;
}
Победителя проверяем после каждого хода. Добавим кода в метод onClick() класса Listener
public void onClick(View view) {
Button button = (Button) view;
Game g = game;
Player player = g.getCurrentActivePlayer();
if (makeTurn(x, y)) {
button.setText(player.getName());
}
Player winner = g.checkWinner();
if (winner != null) {
gameOver(winner);
}
if (g.isFieldFilled()) { // в случае, если поле заполнено
gameOver();
}
}
Метод gameOver() реализован в 2-х вариантах:
private void gameOver(Player player) {
CharSequence text = "Player \"" + player.getName() + "\" won!";
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
game.reset();
refresh();
}
private void gameOver() {
CharSequence text = "Draw";
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
game.reset();
refresh();
}
Для Java, gameOver(Player player) и gameOver() — разные методы. Воспользовавшись Builder’ом Toast.makeText, можно быстро создать и показать уведомление. refresh() обновляет состояние поля:
private void refresh() {
Square[][] field = game.getField();
for (int i = 0, len = field.length; i < len; i++) {
for (int j = 0, len2 = field[i].length; j < len2; j++) {
if (field[i][j].getPlayer() == null) {
buttons[i][j].setText("");
} else {
buttons[i][j].setText(field[i][j].getPlayer().getName());
}
}
}
}
Готово! Надеюсь, эта статья помогла Вам освоиться в мире разработки под OS Android. Благодарю за внимание!
Видео готового приложения
Исходники .
PS: статья была опубликована по просьбе комментаторов этого поста.
Java is one of the powerful general-purpose programming languages, created in 1995 by Sun Microsystems (now owned by Oracle). Java is Object-Oriented. However, it is not considered as pure object-oriented as it provides support for primitive data types (like int, char, etc). Java syntax is similar to C/C++. But Java does not provide low-level programming functionalities like pointers. Also, Java code is always written in the form of classes and objects. Android heavily relies on the Java programming language all the SDKs required to build for android applications use the standard libraries of Java. If one is coming from a traditional programming background like C, C++, Java is easy to learn. So in this discussion, there is a complete guide to learn Java specifically considering Android App Development.
So in this article, we have covered the following things:
- Basics of Java
- Decision Making Statements in Java
- Type Conversion in Java
- Comments in Java
- Operators in Java
- Strings in Java
- Object-Oriented Programming Concepts in Java
- Exception Handling in Java
- Interfaces and Abstract Classes
- Essential collections in Java required for Android Development
- Miscellaneous
- Complete Java Tutorial
Step-by-Step Guide to Learn Java for Android App Development
Basics of Java
- How to start learning Java – understand the core introduction of the Java programming language.
- Setting up the environment – Setup IDE for writing programs in Java.
- The Hello World Example – The first Hello World program in Java.
- Java Class File – Basic entry point of Java programming, which is writing the main class.
- Java Identifiers – In Java, an identifier can be a class name, method name, variable name, or label.
- Data types in Java – Get to know what types of data types are supported by the Java programming language.
- Variables in Java – A variable is a name given to a memory location. It is the basic unit of storage in a program.
- Scope of Variables – The scope of a variable is the part of the program where the variable is accessible.
- Blank Final in Java – A final variable in Java can be assigned a value only once. We can assign a value either in the declaration or later.
Decision Making Statements in Java
- Decision Making in Java (if, if-else, switch, break, continue, jump) – A programming language uses control statements to control the flow of execution of a program based on certain conditions.
- Switch Statement in Java – The switch statement is a multi-way branch statement. It provides an easy way to dispatch execution to different parts of code based on the value of the expression.
- Loops in Java – Looping in programming languages is a feature that facilitates the execution of a set of instructions/functions repeatedly while some conditions are evaluated to be true.
- For-each loop in Java – For-each is another array traversing technique like for loop, while loop, do-while loop is introduced in Java5.
Type Conversion in Java
- Type conversion in Java with Examples – If the data types are compatible, then Java will perform the conversion automatically known as Automatic Type Conversion, and if not, then they need to be cast or converted explicitly.
Comments in Java
- Comments in Java – Comments take part in making the program become more human-readable by placing the details of code involved and proper use of comments makes maintenance easier and finding bugs easier.
Operators in Java
- Operators in Java – Java provides many types of operators which can be used according to the need. They are classified based on the functionality they provide.
Strings in Java
- String class in Java | Set 1 – String is a sequence of characters. In Java, objects of strings are immutable, which means constant and cannot be changed once created.
- StringBuffer class in Java – StringBuffer is a peer class of String that provides much of the functionality of strings.
- StringBuilder Class in Java with Examples – The StringBuilder in Java represents a mutable sequence of characters.
Object-Oriented Programming Concepts in Java
- Classes and Objects in Java – The basic OOPs components Class and Object in the java programming language.
- Different ways to create objects in Java – Get to know the various ways of creating objects in Java.
- Inheritance in Java – It is the mechanism in Java by which one class is allowed to inherit the features(fields and methods) of another class.
- Encapsulation in Java – Encapsulation is defined as the wrapping up of data under a single unit.
- Abstraction in Java – Data Abstraction is a property by virtue of which only the essential details are displayed to the user.
- Access Modifiers in Java – As the name suggests, access modifiers in Java help to restrict the scope of a class, constructor, variable, method, or data member.
- ‘this’ reference in Java – ‘this’ is a reference variable that refers to the current object.
- Overloading in Java – Overloading allows different methods to have the same name, but different signatures of methods.
- Overriding in Java – Overriding is a feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its super-classes or parent classes.
- Object class in Java – Object class is present in the java.lang package. Every class in Java is directly or indirectly derived from the Object class.
- Static class in Java – Some classes can be made static in Java. Java supports Static Instance Variables, Static Methods, Static Block, and Static Classes.
Exception Handling in Java
- Exceptions in Java – An exception is an unwanted or unexpected event that occurs during the execution of a program i.e at run time.
- Types of Exception in Java with Examples – Java also allows users to define their own exceptions.
Interfaces and Abstract Classes
- Interfaces in Java – Like a class, an interface can have methods and variables, but the methods declared in an interface are by default abstract.
- Access specifier of methods in interfaces – All methods in an interface are public, even if we do not specify public with method names. Also, data fields are public static final even if we do not mention them in field names.
- Access specifiers for classes or interfaces in Java – Methods and data members of a class/interface can have one of the following four access specifiers.
- Abstract Classes in Java – Java, a separate keyword abstract is used to make a class abstract.
- Difference between Abstract Class and Interface in Java – Get to know the differences between the interfaces and abstract classes.
- Anonymous Inner Class in Java – It is an inner class without a name and for which only a single object is created.
Essential collections in Java required for Android Development
- ArrayList in Java – ArrayList is a part of the collection framework and is present in the java.util package. It provides us with dynamic arrays in Java.
- HashMap in Java with Examples – It stores the data in (Key, Value) pairs, and you can access it via an index of another type.
Miscellaneous
- Java Naming Conventions – Naming conventions must be followed while developing software in Java for good maintenance and readability of code.
- Generics in Java – Generics mean parameterized types. The idea is to allow types ( Ingers, strings, … etc, and user-defined types) to be a parameter for methods, classes, and interfaces.
- Annotations in Java – Annotations are used to provide supplemental information about a program.
- Lambda Expressions in Java 8 – Lambda expressions basically express instances of functional interfaces (An interface with a single abstract method is called a functional interface.
For a complete Java Tutorial, you may refer to this article: Java Programming Language
Last Updated :
26 Jun, 2021
Like Article
Save Article