Android
This presentation is the property of its rightful owner.
Sponsored Links
1 / 31

Создание удобной архитектуры Android- приложения PowerPoint PPT Presentation


  • 105 Views
  • Uploaded on
  • Presentation posted in: General

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

Download Presentation

Создание удобной архитектуры Android- приложения

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Android

Создание удобной архитектуры Android-приложения

Александр Османов

Android-разработчик, DataArt, Воронеж


Android

Постановка задачи

  • Часто во время работы приложениянеобходимо выполнять продолжительные задачи в фоне:

    • Выполнение HTTP запроса к серверу

    • Математический расчет

  • После выполнения задачи необходимо уведомить UI о завершении, чтобы UI смог обновиться.

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


Android

Почему нетривиально?

  • Часто нужна возможность контроля над очередностью выполнения задач, возможность отмены и отслеживания прогресса выполнения

  • Жизненный цикл визуальных компонентов часто ставит палки в колеса

  • До сих пор нету официально рекомендованной Google организации взаимодействия с сервисом:

    • Broadcasts/Local broadcasts

    • Binding

    • ResultReceiver

    • createPendingResult


Android

Как UI может узнать, что что-то происходит?

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

  • Уведомления, реализованные в приложении — наши нестандартные уведомления, когда мы просто хотим отправить результат или прогресс выполнения фоновой задачи в UI.


Asynctask

AsyncTask?

  • Самый очевидный и простой способ для новичка

  • Позволяет легко указывать, какой код исполнять в фоновом потоке, какой в UI потоке

  • Позволяет публиковать прогресс операции

  • Код пишется легко и быстро


Asynctask1

AsyncTask

  • Смешивание кода, посылающего HTTP запросы, с кодом, отвечающим за UI в вашей Activity

  • Потеря контекста при пересоздании activity

  • Сложно контролировать очередность выполнения запросов

  • Вы не можете управлять процессом, в котором будет выполняться задача


Service

Service!

  • Специально созданный для такого рода задач компонент с независимым жизненным циклом

  • Однако, требует дополнительной работы, чтобы организовать двустороннее общение с Activity


Android

Наброски нашего фреймворка

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

  • Command processor — сервис, отвечающий за планирование и выполнение команд

  • ContentProvider — поможет реализовать хранение данных + управляемые обновления UI.

  • Уведомления UI?


Broadcast

Broadcast

  • После выполнения работы сервис посылает broadcast-сообщение с результатом работы

  • UI получает сообщения при помощи BroadcastReceiver и ожидает входящих сообщений.


Broadcast1

Broadcast

  • Преимущества

    • Легко использовать

    • Легко привязать к жизненному циклу Activity

    • Могут работать между процессами

  • Недостатки

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

    • Также сообщения потенциально могут быть присланы извне другими приложениями. Опять необходимо предпринимать меры.

    • Проходит через системную очередь сообщений


Localbroadcastmanager

LocalBroadcastManager

  • Преимущества

    • Легко использовать

    • Легко привязать к жизненному циклу Activity

    • Не нужно думать о безопасности

  • Недостатки

    • Не могут работать между процессами


Resultreceiver

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 нашему сервису.


Resultreceiver1

ResultReceiver

  • Преимущества

    • Работает как локально, так и через процессы

    • Не нужно думать о безопасности

  • Недостатки

    • Немного сложнее привязать к жизненному циклу Activity


Android

Наброски нашего фреймворка

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

  • Command processor — сервис, отвечающий за планирование и выполнение команд

  • ContentProvider — поможет реализовать хранение данных + управляемые обновления UI.

  • ResultReceiver — для возвращения результата работы фоновой задачи

  • Реестр выполняющихся в данный момент операций


Command processor

Command Processor

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

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

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

  • Команды образуют иерархию, где базовый класс инкапсулирует ResultReceiverи реализует общие методы, например, sendResult(intresultCode, Bundle data).


Command processor1

Command Processor

  • В качестве процессора команд будет выступать Service

    • IntentService

    • Своя реализация сервиса с использованием ExecutorService

  • Команды будут передаваться сервису в виде extras в Intent

  • Сервис будет просто извлекать их и запускать в новом потоке (потоке из пула)

  • Сервис также может хранить соответствие идентификатор-выполняемая команда для возможности реализации отмены команды


Command processor2

Command Processor

BaseCommandcommand = intent.getParcelableExtra(EXTRA_COMMAND);

ResultReceivercallback = intent.getParcelableExtra(EXTRA_STATUS_RECEIVER);

command.execute(intent, context, callback);


Command processor3

Command Processor

ExecutorService

Service

Command 1

ResultReceiver


Servicehelper

ServiceHelper

  • ServiceHelper — это промежуточный слой между UI и сервисом, скрывающий рутину по созданию интентов сервису и предоставляющий нашему UI лишь набор бизнес методов для вызова.

  • Также он координирует ответы от сервиса и содержит информацию о командах, выполняющихся в данный момент.

  • ServiceHelper«живет» в Application scope приложения


Servicehelper1

ServiceHelper

  • Дополнительные методы ServiceHelper

    • isExecuting(intrequestId)

    • cancelCommand(intrequestId)

    • addListener(ServiceCallbackListener listener)

    • removeListener(ServiceCallbackListener listener)

  • Пример:

    • public intaskServer(String question)


Android

Принцип работы

  • Activity вызывает бизнес-метод ServiceHelper

  • ServiceHelper генерирует и сохраняет ID запроса, запоминает, что данная команда выполняется

  • Собирает Intent, в который вкладывет ResultReceiver, экземпляр команды и отправляет сервису

  • Когда сервис завершает операцию, ServiceHelper отвечает за то, чтобы все активные Activity получили результат


Servicecallbacklistener

ServiceCallbackListener

  • Слушателем может быть что угодно. Для удобства я сделал базовый класс Activity, выступающий в роли слушателя и подписывающийся на обновления при запуске.

  • Это позволяет в реализациях Activity просто переопределить метод onServiceCallback и реализовать в нем логику аналогично тому, как это делается со стандартными callback-методами системы.


Servicecallbacklistener1

ServiceCallbackListener

  • void onServiceResult(intrequestId, Intent intent,intresultCode, Bundle resultData);

    • requestIdпозволяет нам идентифицировать конкретный запрос

    • Intent позволит нам идентифицировать класс команды, если нас не интерует конкретный запрос

    • resultCode, resultData – позволят обработать результат выполнения команды


Android

Принцип работы

Application

Activity

Listener

ServiceHelper

Receiver

Command

Service

Provider

Comand 1

Comand 2


Android

Отложенная проверка

  • Имея ID запроса, мы можем выполнять отложенную проверку. Представим последовательность:

    • пользователь запустил действие, запустилась крутилка

    • закрыл приложение на 2 минуты

    • действие уже выполнилось

    • пользователь открыл снова

  • тут мы проверяем в onResume, выполнилась ли операция, и убираем крутилку

    • т. е., просто вызываем getServiceHelper().isPending(requestId), если нам это нужно.


Android

Расширение №1. Отмена выполнения

  • В базовый класс запрос добавим метод cancel()

  • Добавим метод cancelCommand(intcommandId) в ServiceHelper

  • Метод посылает Intent в сервис, который находит команду по идентификатору и вызывает cancel()


Android

Расширение №2. Прогресс операции

  • Добавляем новый resultCodeпомимо SUCCESS и ERROR, и все.


Android

Сторонние библиотеки, которые нам помогут

  • Ottoот Square – очень удобная реализация event bus. В нашей схеме подойдет для передачирезультатов команды

    • Использует reflection

    • Работает только в одном процессе и одном потоке

  • Groundy – неплохая библиотека, реализующая command processor на основе генерации кода


Android

В итоге мы получили

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

  • Поддержка жизненного цикла Activity

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

  • Возможность управлять стратегией выполнения задач меняя реализацию сервиса (IntentService vs ExecutorService)

  • Расширяемость


Android

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

  • Github - http://goo.gl/4voFM


Android

Спасибо за внимание!

Вопросы?


  • Login