Создание удобной архитектуры Android-приложения Александр Османов Android-разработчик, DataArt, Воронеж.

Презентация:



Advertisements
Похожие презентации
Мобильная связь в приложениях для смартфона Лекция 5 Авторы: Березовская Ю.В., Латухина Е.А., Юфрякова О.А.
Advertisements

Калугин Александр, PhD, PMP Mercury Development Project Director.
Технология модели «клиент-сервер». Роли Компьютер, управляющий тем или иным ресурсом, принято называть сервером этого ресурса Компьютер, желающий воспользоваться.
©Павловская Т.А. (СПбГУ ИТМО) Курс «С#. Программирование на языке высокого уровня» Павловская Т.А.
Технические возможности. Наши цели Максимальная гибкость Максимальная скорость считывания и обработки данных Стабильность работы Максимальная простота.
Архитектура компьютера. Принципы Дж.фон Неймана арифметико-логическое устройство (АЛУ), отвечающее за арифметические и логические операции; устройство.
Пользовательский интерфейс для нескольких проектов Александр Веселов.
Магистрально-модульный принцип построения компьютера Устройство компьютера.
Архитектура операционных систем. Архитектура ОС Состав модулей (компонент) ОС Структура связей между отдельными модулями ОС Принципы взаимодействия модулей.
Это комплекс взаимосвязанных системных программ, назначение которого организовать взаимодействие пользователя с компьютером и выполнение всех других программ.
Team System - фреймворк для автоматизации тестирования от Microsoft Футорняк Елена Apriorit Сообщество Тестировщиков Днепропетровска 29/09/2011.
Архитектура операционных систем Семестр 2, Лекция 1.
Внешний документооборот с контрагентами. 2 Зачем нужно автоматизировать обмен документами Переход к электронному документообороту. Сокращение действий,
Лекция 4. Режимы работы микропроцессора. Взаимодействие микропроцессора с остальными устройствами Взаимодействие МП с остальными устройствами МПС происходит.
Контроль за эффективностью использования IT-инфраструктуры с точки зрения бизнеса при помощи Progress Actional. Соколов Максим, Progress Technologies.
Структурная схема компьютера Взаимодействие устройств компьютера.
ОРГАНИЗАЦИЯ БАЗ ДАННЫХ И ЗНАНИЙ ТЕМА 5 СТРУКТУРИРОВАННЫЙ ЯЗЫК ЗАПРОСОВ SQL.
Безопасность сервисов Дмитрий Истомин, директор по развитию Уральского центра систем безопасности.
Единая система аутентификации Обзор решения Москва, 2012г.
Тема 1.3. Сервисное программное обеспечение. 1. Понятие операционного окружения Операцио́нное окруже́ние (англ. operating environment) среда, в которой.
Транксрипт:

Создание удобной архитектуры Android-приложения Александр Османов Android-разработчик, DataArt, Воронеж

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

Почему нетривиально? Часто нужна возможность контроля над очередностью выполнения задач, возможность отмены и отслеживания прогресса выполнения Жизненный цикл визуальных компонентов часто ставит палки в колеса До сих пор нету официально рекомендованной Google организации взаимодействия с сервисом: –Broadcasts/Local broadcasts –Binding –ResultReceiver –createPendingResult

Как UI может узнать, что что-то происходит? «Управляемые» платформой компоненты, реализующие ContentObserver. В случае использования приложением ContentProvider, а также адаптеров курсора подобные обновления достаются нам «бесплатно». О них речь не пойдет. Уведомления, реализованные в приложении наши нестандартные уведомления, когда мы просто хотим отправить результат или прогресс выполнения фоновой задачи в UI.

AsyncTask? Самый очевидный и простой способ для новичка Позволяет легко указывать, какой код исполнять в фоновом потоке, какой в UI потоке Позволяет публиковать прогресс операции Код пишется легко и быстро

AsyncTask Смешивание кода, посылающего HTTP запросы, с кодом, отвечающим за UI в вашей Activity Потеря контекста при пересоздании activity Сложно контролировать очередность выполнения запросов Вы не можете управлять процессом, в котором будет выполняться задача

Service! Специально созданный для такого рода задач компонент с независимым жизненным циклом Однако, требует дополнительной работы, чтобы организовать двустороннее общение с Activity

Наброски нашего фреймворка Command каждая задача, которую мы хотим выполнять в фоне отдельный класс-команда Command processor сервис, отвечающий за планирование и выполнение команд ContentProvider поможет реализовать хранение данных + управляемые обновления UI. Уведомления UI?

Broadcast После выполнения работы сервис посылает broadcast- сообщение с результатом работы UI получает сообщения при помощи BroadcastReceiver и ожидает входящих сообщений.

Broadcast Преимущества –Легко использовать –Легко привязать к жизненному циклу Activity –Могут работать между процессами Недостатки –Необходимо предпринять меры по защите сообщений, либо установив разрешения, либо ограничив принимающие пакеты –Также сообщения потенциально могут быть присланы извне другими приложениями. Опять необходимо предпринимать меры. –Проходит через системную очередь сообщений

LocalBroadcastManager Преимущества –Легко использовать –Легко привязать к жизненному циклу Activity –Не нужно думать о безопасности Недостатки –Не могут работать между процессами

ResultReceiver Generic interface for receiving a callback result from someone. Use this by creating a subclass and implement onReceiveResult(int, Bundle), which you can then pass to others and send through IPC, and receive results they supply with send(int, Bundle). Мы можем отправить экземпляр ResultReceiver прямо как extra в Intent нашему сервису.

ResultReceiver Преимущества –Работает как локально, так и через процессы –Не нужно думать о безопасности Недостатки –Немного сложнее привязать к жизненному циклу Activity

Наброски нашего фреймворка Command каждая задача, которую мы хотим выполнять в фоне отдельный класс-команда Command processor сервис, отвечающий за планирование и выполнение команд ContentProvider поможет реализовать хранение данных + управляемые обновления UI. ResultReceiver для возвращения результата работы фоновой задачи Реестр выполняющихся в данный момент операций

Command Processor Каждая задача, которую необходимо выполнить, будет инкапсулирована в класс-команду Каждая команда будет реализовывать Parcelable для более удобной передачи ее сервису Для каждой выполняемой команды будет создаваться уникальный идентификатор Команды образуют иерархию, где базовый класс инкапсулирует ResultReceiver и реализует общие методы, например, sendResult(int resultCode, Bundle data).

Command Processor В качестве процессора команд будет выступать Service –IntentService –Своя реализация сервиса с использованием ExecutorService Команды будут передаваться сервису в виде extras в Intent Сервис будет просто извлекать их и запускать в новом потоке (потоке из пула) Сервис также может хранить соответствие идентификатор- выполняемая команда для возможности реализации отмены команды

Command Processor BaseCommand command = intent.getParcelableExtra(EXTRA_COMMAND); ResultReceiver callback = intent.getParcelableExtra(EXTRA_STATUS_RECEIVER); command.execute(intent, context, callback);

Command Processor Service ExecutorService Command 1 ResultReceiver

ServiceHelper ServiceHelper это промежуточный слой между UI и сервисом, скрывающий рутину по созданию интентов сервису и предоставляющий нашему UI лишь набор бизнес методов для вызова. Также он координирует ответы от сервиса и содержит информацию о командах, выполняющихся в данный момент. ServiceHelper «живет» в Application scope приложения

ServiceHelper Дополнительные методы ServiceHelper –isExecuting(int requestId) –cancelCommand(int requestId) –addListener(ServiceCallbackListener listener) –removeListener(ServiceCallbackListener listener) Пример: –public int askServer(String question)

Принцип работы Activity вызывает бизнес-метод ServiceHelper ServiceHelper генерирует и сохраняет ID запроса, запоминает, что данная команда выполняется Собирает Intent, в который вкладывет ResultReceiver, экземпляр команды и отправляет сервису Когда сервис завершает операцию, ServiceHelper отвечает за то, чтобы все активные Activity получили результат

ServiceCallbackListener Слушателем может быть что угодно. Для удобства я сделал базовый класс Activity, выступающий в роли слушателя и подписывающийся на обновления при запуске. Это позволяет в реализациях Activity просто переопределить метод onServiceCallback и реализовать в нем логику аналогично тому, как это делается со стандартными callback-методами системы.

ServiceCallbackListener void onServiceResult(int requestId, Intent intent, int resultCode, Bundle resultData); –requestId позволяет нам идентифицировать конкретный запрос –Intent позволит нам идентифицировать класс команды, если нас не интерует конкретный запрос –resultCode, resultData – позволят обработать результат выполнения команды

Принцип работы Application ServiceHelper Service Comand 1Comand 2 ActivityListener Provider Receiver Command

Отложенная проверка Имея ID запроса, мы можем выполнять отложенную проверку. Представим последовательность: –пользователь запустил действие, запустилась крутилка –закрыл приложение на 2 минуты –действие уже выполнилось –пользователь открыл снова тут мы проверяем в onResume, выполнилась ли операция, и убираем крутилку –т. е., просто вызываем getServiceHelper().isPending(requestId), если нам это нужно.

Расширение 1. Отмена выполнения В базовый класс запрос добавим метод cancel() Добавим метод cancelCommand(int commandId) в ServiceHelper Метод посылает Intent в сервис, который находит команду по идентификатору и вызывает cancel()

Расширение 2. Прогресс операции Добавляем новый resultCode помимо SUCCESS и ERROR, и все.

Сторонние библиотеки, которые нам помогут Otto от Square – очень удобная реализация event bus. В нашей схеме подойдет для передачи результатов командыOtto –Использует reflection –Работает только в одном процессе и одном потоке Groundy – неплохая библиотека, реализующая command processor на основе генерации кодаGroundy

В итоге мы получили Гибкую архитектуру для выполнения задач в фоне с поддержкой уведомлений UI Поддержка жизненного цикла Activity Возможность легко вынести выполнение задач в отдельный процесс, просто выставив атрибут сервису в манифесте Возможность управлять стратегией выполнения задач меняя реализацию сервиса (IntentService vs ExecutorService) Расширяемость

Пример исходного кода Github -

Спасибо за внимание! Вопросы?