android
Download
Skip this Video
Download Presentation
Создание удобной архитектуры Android- приложения

Loading in 2 Seconds...

play fullscreen
1 / 31

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


  • 190 Views
  • Uploaded on

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

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Создание удобной архитектуры Android- приложения' - alexa-carlson


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, Воронеж

slide2
Постановка задачи
  • Часто во время работы приложениянеобходимо выполнять продолжительные задачи в фоне:
    • Выполнение HTTP запроса к серверу
    • Математический расчет
  • После выполнения задачи необходимо уведомить UI о завершении, чтобы UI смог обновиться.
  • Во время выполнения задачи может понадобиться узнать прогресс выполнения задачи
slide3
Почему нетривиально?
  • Часто нужна возможность контроля над очередностью выполнения задач, возможность отмены и отслеживания прогресса выполнения
  • Жизненный цикл визуальных компонентов часто ставит палки в колеса
  • До сих пор нету официально рекомендованной Google организации взаимодействия с сервисом:
    • Broadcasts/Local broadcasts
    • Binding
    • ResultReceiver
    • createPendingResult
slide4
Как UI может узнать, что что-то происходит?
  • «Управляемые» платформой — компоненты, реализующие ContentObserver. В случае использования приложением ContentProvider, а также адаптеров курсора подобные обновления достаются нам «бесплатно». О них речь не пойдет.
  • Уведомления, реализованные в приложении — наши нестандартные уведомления, когда мы просто хотим отправить результат или прогресс выполнения фоновой задачи в UI.
asynctask
AsyncTask?
  • Самый очевидный и простой способ для новичка
  • Позволяет легко указывать, какой код исполнять в фоновом потоке, какой в UI потоке
  • Позволяет публиковать прогресс операции
  • Код пишется легко и быстро
asynctask1
AsyncTask
  • Смешивание кода, посылающего HTTP запросы, с кодом, отвечающим за UI в вашей Activity
  • Потеря контекста при пересоздании activity
  • Сложно контролировать очередность выполнения запросов
  • Вы не можете управлять процессом, в котором будет выполняться задача
service
Service!
  • Специально созданный для такого рода задач компонент с независимым жизненным циклом
  • Однако, требует дополнительной работы, чтобы организовать двустороннее общение с Activity
slide8
Наброски нашего фреймворка
  • 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
slide14
Наброски нашего фреймворка
  • 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)
slide21
Принцип работы
  • 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 – позволят обработать результат выполнения команды
slide24
Принцип работы

Application

Activity

Listener

ServiceHelper

Receiver

Command

Service

Provider

Comand 1

Comand 2

slide25
Отложенная проверка
  • Имея ID запроса, мы можем выполнять отложенную проверку. Представим последовательность:
    • пользователь запустил действие, запустилась крутилка
    • закрыл приложение на 2 минуты
    • действие уже выполнилось
    • пользователь открыл снова
  • тут мы проверяем в onResume, выполнилась ли операция, и убираем крутилку
    • т. е., просто вызываем getServiceHelper().isPending(requestId), если нам это нужно.
slide26
Расширение №1. Отмена выполнения
  • В базовый класс запрос добавим метод cancel()
  • Добавим метод cancelCommand(intcommandId) в ServiceHelper
  • Метод посылает Intent в сервис, который находит команду по идентификатору и вызывает cancel()
slide27
Расширение №2. Прогресс операции
  • Добавляем новый resultCodeпомимо SUCCESS и ERROR, и все.
slide28
Сторонние библиотеки, которые нам помогут
  • Ottoот Square – очень удобная реализация event bus. В нашей схеме подойдет для передачирезультатов команды
    • Использует reflection
    • Работает только в одном процессе и одном потоке
  • Groundy – неплохая библиотека, реализующая command processor на основе генерации кода
slide29
В итоге мы получили
  • Гибкую архитектуру для выполнения задач в фоне с поддержкой уведомлений UI
  • Поддержка жизненного цикла Activity
  • Возможность легко вынести выполнение задач в отдельный процесс, просто выставив атрибут сервису в манифесте
  • Возможность управлять стратегией выполнения задач меняя реализацию сервиса (IntentService vs ExecutorService)
  • Расширяемость
slide30
Пример исходного кода
  • Github - http://goo.gl/4voFM
ad