- Введение в структуру android-проекта
- Вступление
- Иерархия проектов Android
- Бегущий поток
- Архитектура Android-приложений… Правильный путь?
- Приступая к работе
- Наш сценарий
- Android-архитектура
- Presentation Layer (Слой представления)
- Domain Layer (Слой бизнес-логики)
- Data Layer (Слой данных)
- Обработка ошибок
- Тестирование
- Покажите мне код
- Заключение
- Пишем первое приложение для Android
- Установка необходимых программ и утилит
- Запуск виртуального устройства
- Список устройств
- Создание проекта
- Структура проекта
- Первые строки
- Square.java
- Player.java
- Game.java
- Определение победителя
- WinnerCheckerHorizontal.java
- WinnerCheckerVertical.java
- WinnerCheckerDiagonalLeft.java
- WinnerCheckerDiagonalRight.java
- Видео готового приложения
Введение в структуру android-проекта
Введение Цель этой статьи – дать вам представление о проекте Android… С тегом android, java.
Автор: Amr Hassan AbdUllah
Дата записи
Вступление
Цель этой статьи – дать вам представление о структуре проекта Android.
Вы готовы?, Пришло время для истории, мы хотим создать приложение с одной страницей, на которой есть одна кнопка, и всякий раз, когда вы нажимаете на эту кнопку, она выдает пользователю сообщение о том, что кнопка была нажата.
Итак, вы начинаете с создания проекта Android с пустой активностью над android studio но появляется дикая иерархия проектов
Иерархия проектов Android
Вот наиболее часто используемые папки
- манифесты (вы можете указать разрешения здесь, здесь определено имя вашего пакета, здесь должно быть указано каждое действие, услуга, все)
- java/ваш-пакет (содержит вашу логику, сотрудникам нравится то, что вы хотите сделать, когда пользователь открывает приложение, нажимает на кнопку. и т. Д.)
- res
- рисоваемый (Содержит логотип, изображения)
- макет (Дизайн и содержание ваших страниц)
- значения (любое описание, заголовок в основном любой текст в пользовательском интерфейсе должен быть написан здесь и указан в макетах)
- сборка.gradle (модуль) (Место, где вы устанавливаете свои зависимости, добавляете различные типы сборок, управляете версиями своих сборок)
Конечно, есть и другие папки и файлы, но это те, с которыми вам придется иметь дело больше всего.
Бегущий поток
Когда вы запускаете приложение, первое, что выполняется, – это MainActivity , и любое действие имеет описанный выше жизненный цикл, в котором оно вызывает onCreate() в начале, так что там мы найдем рендеринг основного макета.
Которые, в свою очередь, начинают визуализировать упомянутый макет внутри папки /res/layout , где он содержит что-то похожее на это
Обратите внимание на эту строку
В нем говорится компоновка ограничений можете ли вы догадаться, что это может означать? это подразумевает, что существуют разные макеты. Так что же это такое? и какой из них вам следует использовать? Существует множество макетов, например Макет стека, относительный вывод, вывод сетки… и т. Д. У каждого есть свои варианты использования. Но если у вас большой и сложный дизайн с какой-то взаимосвязью между родственными представлениями и родительским макетом, то contraintLayout подходит именно вам.
например, если вы хотите разместить текст в середине представления, вы можете просто добавить его в определение элемента
Обратите внимание на эту строку
При этом будет использоваться значение, определенное в values/strings.xml до тех пор, пока он имеет то же имя и тип
Это означает, что при отображении представления на нем будет отображаться кнопка с текстовым щелчком!
Как вы можете видеть, в макете определена кнопка, но нам нужно добавить прослушиватель щелчков над кнопкой, чтобы, когда пользователь нажимает на нее, мы могли что-то сделать, и вот тогда этот android: атрибут над кнопкой пригодится, поэтому в Основном действии внутри метода onCreate мы можем сказать
Таким образом, всякий раз, когда нажимается кнопка с ключом android:id=»@+id/my_button» , будет выполняться функция onclick
Поздравляю!! вы закончили рассказ, и у вас есть кнопка, которая при каждом нажатии будет показывать сообщение.
Увидимся в следующей части
Фотография на обложке Марка Босса вкл Расплескать
Источник
Архитектура Android-приложений… Правильный путь?
От переводчика: Некоторые термины, которые использует автор, не имеют общепринятого перевода (ну, или я его не знаю:), поэтому я решил оставить большинство на языке оригинала — они всё равно понятны и для тех, кто пишет под android, но не знает английский.
Куда писать об ошибках и неточностях, вы знаете.
За последние несколько месяцев, а также после дискуссий на Tuenti с коллегами вроде @pedro_g_s и @flipper83 (кстати говоря, 2 крутых Android-разработчика), я решил, что имеет смысл написать заметку о проектировании Android-приложений.
Цель поста — немного рассказать о подходе к проектированию, который я продвигал в последние несколько месяцев, и также поделиться всем тем, что я узнал во время исследования и реализации этого подхода.
Приступая к работе
Мы знаем, что написание качественного программного обеспечения — сложное и многогранное занятие: программа должна не только соответствовать установленным требованиям, но и быть надёжной, удобной в сопровождении, тестируемой и достаточно гибкой для добавления или изменения функций. И здесь появляется понятие “стройной архитектуры”, которое неплохо бы держать в уме при разработке любого приложения.
Идея проста: стройная архитектура основывается на группе методов, реализующих системы, которые являются:
- Независимыми от фреймворков.
- Тестируемыми.
- Независимыми от UI.
- Независимыми от БД.
- Независимыми от любой внешней службы.
Кругов необязательно должно быть 4 (как на диаграмме), это просто схема; важно учитывать Правило Зависимостей: код должен иметь зависимости только во внутренние круги и не должен иметь никакого понятия, что происходит во внешних кругах.
Вот небольшой словарь терминов, необходимых для лучшего понимания данного подхода:
- Entities (Сущности): это бизнес-логика приложения.
- Use Cases (Методы использования): эти методы организуют поток данных в Entities и из них. Также их называют Interactors (Посредниками).
- Interface Adapters (Интерфейс-Адаптеры): этот набор адаптеров преобразовывает данные из формата, удобного для Методов использования и Сущностей. К этим адаптерами принадлежат Presenter-ы и Controller-ы.
- Frameworks and Drivers: место скопления деталей: UI, инструменты, фреймворки, БД и т. д.
Для лучшего понимания обратитесь к данной статье или к данному видео.
Наш сценарий
Я начал с простого, чтобы понять, как обстоят дела: создал простенькое приложение, которое отображает список друзей, который получает с облака, а при клике по другу отображает более детальную информацию о нём на новом экране.
Я оставлю здесь видео, чтобы вы поняли, о чем идёт речь:
Android-архитектура
Наша цель — разделение задач таким образом, чтобы бизнес-логика ничего не знала о внешнем мире, так, чтобы можно было тестировать её без никаких зависимостей и внешних элементов.
Для достижения этого я предлагаю разбить проект на 3 слоя, каждый из которых имеет свою цель и может работать независимо от остальных.
Стоит отметить, что каждый слой использует свою модель данных, таким образом можно достигнуть необходимой независимости (вы можете увидеть в коде, для выполнения трансформации данных необходим преобразователь данных (data mapper). Это вынужденная плата за то, чтобы модели внутри приложения не пересекались). Вот схема, как это выглядит:
Примечание: я не использовал внешних библиотек (кроме gson для парсинга json и junit, mockito, robolectric и espresso для тестирования) для того, чтобы пример был более наглядным. В любом случае, не стесняйтесь использовать ORM для хранения информации или любой dependency injection framework, да и вообще инструменты или библиотеки, которые делают вашу жизнь легче (помните: изобретать велосипед заново — не лучшая идея).
Presentation Layer (Слой представления)
Здесь логика связывается с Views (Представлениями) и происходят анимации. Это не что иное, как Model View Presenter (то есть, MVP), но вы можете использовать любой другой паттерн вроде MVC или MVVM. Я не буду вдаваться в детали, но fragments и activities — это всего лишь views, там нету никакой логики кроме логики UI и рендеринга этого самого отображения. Presenter-ы на этом слое связываются с interactors (посредниками), что предполагает работу в новом потоке (не в UI-потоке), и передачи через коллбэки информации, которая будет отображена во view.
Если вы хотите увидеть крутой пример эффективного Android UI, который использует MVP и MVVM, взгляните на пример реализации от моего друга Pedro Gómez.
Domain Layer (Слой бизнес-логики)
Вся логика реализована в этом слое. Рассматривая проект, вы увидите здесь реализацию interactor-ов (Use Cases — методы использования).
Этот слой — модуль на чистой джаве без никаких Android-зависимостей. Все внешние компоненты используют интерфейсы для связи с бизнес-объектами.
Data Layer (Слой данных)
Все данные, необходимые для приложения, поставляются из этого слоя через реализацию UserRepository (интерфейс находится в domain layer — слое бизнес-логики), который использует Repository Pattern со стратегией, которая, через фабрику, выбирает различные источники данных, в зависимости от определенных условий.
Например, для получения конкретного пользователя по id источником данных выбирается дисковый кэш, если пользователь уже загружен в него, в противном случае облаку отправляется запрос на получение данных для дальнейшего сохранения в тот же кэш.
Идея всего этого заключается в том, что происхождение данных является понятным для клиента, которого не волнует, поступают данные из памяти, кэша или облака, ему важно только то, что данные будут получены и доступны.
Примечание: что касается кода, помня, что код — это учебный пример, я реализовал очень простой, даже примитивный кэш, используя хранения shared preferences. Помните: НЕ СТОИТ ИЗОБРЕТАТЬ ВЕЛОСИПЕД, если существуют библиотеки, хорошо решающие поставленную задачу.
Обработка ошибок
Это большая тема, в которой всегда есть, что обсудить (и здесь автор предлагает делиться своими решениями). Что до моей реализации, я использовал коллбэки, которые, на случай, если что-то случается, скажем, в хранилище данных, имеют 2 метода: onResponse() и onError(). Последний инкапсулирует исключения во wrapper class (класс-обертку) под названием “ErrorBundle”: Такой подход сопряжен с некоторыми трудностями, потому что бывают цепочки обратных вызовов один за другим, пока ошибка не выходит на presentation layer, чтобы отобразиться. Читаемость кода из-за этого может быть немного нарушена.
С другой стороны, я реализовал систему event bus, которая бросает события, если что-то не так, но такое решение похоже на использование GOTO, и, по-моему, иногда, если не управлять событиями предельно внимательно, можно заблудиться в цепи событий, особенно когда их одновременно бросается несколько.
Тестирование
Что касается тестирования, я применил несколько решений, в зависимости от слоя.
- Presentation Layer: существующий android инструментал и espresso для интеграции и функционального тестирования.
- Domain Layer: JUnit + mockito использовались для юнит-тестов.
- Data Layer: Robolectric (так как этот слой имеет android-зависимости) + junit + для интеграции и юнит-тестов.
Покажите мне код
Думаю, в этом месте вам интересно посмотреть на код. Что ж, вот ссылка на github, где можно найти, что же у меня получилось. Что стоит упомянуть о структуре папок так это то, что разные слои представлены разными модулями:
- presentation: это android-модуль для presentation layer.
- domain: java-модуль без android-зависимостей.
- data: android-модуль, откуда поступают все данные.
- data-test: тесты для data layer. Из-за определённых ограничений, при использовании Robolectric мне пришлось использовать отдельный java-модуль.
Заключение
Дядя Боб сказал: “Архитектура — это намерения, а не фреймворки”, и я полностью с ним согласен. Конечно, есть разные способы реализовать какую-либо вещь, и я уверен, что вы, как и я, каждый день сталкиваетесь с трудностями в этой области, но используя данные приёмы, вы сможете быть уверены, что ваше приложение будет:
- Простым в поддержке.
- Простым в тестировании.
- Составлять единое целое,
- Будучи разделённым.
В заключение я настоятельно рекомендую вам попробовать эти методы, посмотреть на результат и поделиться своим опытом как в отношении этого, так любого другого подхода, который, по вашим наблюдениям, работает лучше: мы уверены, что постоянное совершенствование всегда полезно и положительно.
Источник
Пишем первое приложение для Android
В любом деле самое сложное — это начало. Часто бывает тяжело войти в контекст, с чем столкнулся и я, решив разработать свое первое 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 строчками:
Метод setContentView (равносильно this.setContentView) устанавливает xml-макет для текущего экрана. Далее xml-макеты будем называть «layout», а экраны — «Activity». Layout в приложении будет следующий:
Для этого приложения идеально подойдет TableLayout. Id можно присвоить любому ресурсу. В данном случае, TableLayout присвоен При помощи метода findViewById() можно получить доступ к виду:
Теперь необходимо реализовать метод buildGameField(). Для этого требуется сгенерировать поле в виде матрицы. Этим будет заниматься класс Game. Сначала нужно создать класс Square для ячеек и класс Player, объекты которого будут заполнять эти ячейки.
Square.java
Player.java
Все классы нашего приложения находятся в папке src.
Game.java
Инициализация Game в конструкторе KrestikinolikiActivity.
Метод buildGameField() класса KrestikinolikiActivity. Он динамически добавляет строки и колонки в таблицу (игровое поле):
В строке 8 создается объект, реализующий интерфейс View.OnClickListener. Создадим вложенный класс Listener. Он будет виден только из KrestikinolikiActivity.
Осталось реализовать логику игры.
Определение победителя
К. О. подсказывает, что в крестики-нолики выирывает тот, кто выстроет X или O в линию длиной, равной длине поля по-вертикали, или по-горизонтали, или по-диагонали. Первая мысль, которая приходит в голову — это написать методы для каждого случая. Думаю, в этом случае хорошо подойдет паттерн Chain of Responsobility. Определим интерфейс
Так как Game наделен обязанностью выявлять победителя, он реализует этот интерфейс. Настало время создать виртуальных «лайнсменов», каждый из которых будет проверять свою сторону. Все они реализует интерфейс WinnerCheckerInterface.
WinnerCheckerHorizontal.java
WinnerCheckerVertical.java
WinnerCheckerDiagonalLeft.java
WinnerCheckerDiagonalRight.java
Проинициализируем их в конструкторе Game:
Победителя проверяем после каждого хода. Добавим кода в метод onClick() класса Listener
Метод gameOver() реализован в 2-х вариантах:
Для Java, gameOver(Player player) и gameOver() — разные методы. Воспользовавшись Builder’ом Toast.makeText, можно быстро создать и показать уведомление. refresh() обновляет состояние поля:
Готово! Надеюсь, эта статья помогла Вам освоиться в мире разработки под OS Android. Благодарю за внимание!
Видео готового приложения
PS: статья была опубликована по просьбе комментаторов этого поста.
Источник