Выделение бизнес-
                      логики в сервис
                     Дмитрий Викторович Малыханов
                                DataArt



The Android robot is reproduced or modified from work created and shared by Google and used according to terms described in the
Creative Commons 3.0 Attribution License.
Что, где, когда
       зачем нужны сервисы
Происхождение видов
     какие бывают сервисы
Раз два три четыре пять
       начинаем выполнять
Получите и распишитесь
      доставка результатов
Что, где, когда
зачем и почему нам нужны сервисы
Альтернативы

Просто:                   Service:

● Thread (pool)
  ○ Возврат в UI thread
● AsyncTask
  ○ Последовательно
  ○ Малое время жизни
● Application
                                     ?
  ○ Засорение кучи
  ○ Нет IPC
Альтернативы

Просто:                   Service:

● Thread (pool)
  ○ Возврат в UI thread
● AsyncTask
  ○ Последовательно
  ○ Малое время жизни
● Application
                                     ?
  ○ Засорение кучи
  ○ Нет IPC
Альтернативы

Просто:                   Service:

● Thread (pool)
  ○ Возврат в UI thread
● AsyncTask
  ○ Последовательно
  ○ Малое время жизни
● Application
                                     ?
  ○ Засорение кучи
  ○ Нет IPC
Альтернативы

Просто:                   Service:

● Thread (pool)           ● Thread/Pool/Etc.
  ○ Возврат в UI thread     ○ Гибкое управление
● AsyncTask               ● Wake Locks
  ○ Последовательно         ○ Гарантия CPU
  ○ Малое время жизни     ● Lifetime
● Application               ○ Сам за себя
  ○ Засорение кучи
  ○ Нет IPC
Альтернативы

Просто:                   Service:

● Thread (pool)           ● Thread/Pool/Etc.
  ○ Возврат в UI thread     ○ Гибкое управление
● AsyncTask               ● Wake Locks
  ○ Последовательно         ○ Гарантия CPU
  ○ Малое время жизни     ● Lifetime
● Application               ○ Сам за себя
  ○ Засорение кучи
  ○ Нет IPC
Альтернативы

Просто:                   Service:

● Thread (pool)           ● Thread/Pool/Etc.
  ○ Возврат в UI thread     ○ Гибкое управление
● AsyncTask               ● Wake Locks
  ○ Последовательно         ○ Гарантия CPU
  ○ Малое время жизни     ● Lifetime
● Application               ○ Сам за себя
  ○ Засорение кучи
  ○ Нет IPC
Какова цена?



●   IPC
●   Ресурсы
●   Безопасность
Какова цена?



           ●   IPC
           ●   Ресурсы
           ●   Безопасность
AndroidManifest.xml:

       <service ... android:exported="false" />
Происхождение
        видов
или какие бывают сервисы
Сервисы простейшие

IntentService:


● одна нить
● очередь задач
● жизненный цикл



http://goo.gl/TvtbV
Колония простейших

Две/три задачи параллельно:

<service android:name=".FirstIntentService" />

<service android:name=".SecondIntentService" />

<service android:name=".ThirdIntentService" />
Высокоорганизованные

ExecutorService:

● ThreadPoolExecutor
● Scheduled
   ThreadPoolExecutor



http://goo.gl/mwV90
Контроль: проблема

IntentService           ThreadPoolService

                                ?
Контроль: решение

 startId -> ConcurrentLinkedQueue

                     Запросы: 1, 2, 3, 4, 5
Thread      1           3        4      4       4     idle
Thread      2           2        2      5      idle   idle


Queue    1,2,3,4,5    2,3,4,5   3,4,5   4, 5    5     STOP
Раз два три четыре
           пять
начинаем правильно выполнять
Что и как делаем?

switch (cmdId) {
   case CMD_POLL:
      poll();          Расширение
      break;           функциональности?
   case CMD_UPLOAD:
      upload();
      break;
                  if ("poll".equals(cmd)) {
                     poll();
                  } else if ("upload".equals(cmd)) {
                     upload();
                  }
Независимость

GoF: Command Pattern


interface Command {

    void execute(Context);

}                               4
http://goo.gl/hwFY9
Идентификаторы

public static final int CMD_POLL = 10;
public static final int CMD_UPLOAD = 20;
...




               Command.class.hashCode()

               System.identityHashCode()
Доставка команд

switch (commandId) {
    case CMD_POLL:
        return new PollCommand().execute();
    case CMD_UPLOAD:
        return new UploadCommand().execute();
...


  abstract class Command
      implements Parcelable {

      public abstract void execute(...);
  }
Не все равны

Последовательное выполнение команд:

                 Command.isSerial()

frameworks/base/core/java/android/os/AsyncTask.java:



private static class SerialExecutor
    implements Executor {
...
Получите и
    распишитесь
доставка результатов
Упаковка для данных


    ●   Entity Bean




●       android.os.Bundle
Упаковка для данных


    ●   Entity Bean
          ДА: типизация
            ○

          НЕТ: затраты CPU
            ○

          НЕТ: IPC
            ○



●       android.os.Bundle
        ○ ДА: нет преобразований
        ○ НЕТ: только Parcelable
Упаковка для данных


    ●   Entity Bean
          ДА: типизация
            ○

          НЕТ: затраты CPU
            ○

          НЕТ: IPC
            ○



●       android.os.Bundle
        ○ ДА: нет преобразований
        ○ НЕТ: только Parcelable
Универсальная упаковка



public class EntityBean
         implements Parcelable
{
...




http://goo.gl/QSFPe
Serializable? НЕТ!

Serializable - лучшее из трёх?

         Parcelable
     ^
     С
     к
     о
     р                  5..10 раз
     о
     с
     т
     ь
     ^   Serializable
Билет в один конец

Способ доставки:
  ● broadcast

Проблемы:
  ● IPC
  ● wakelock
  ● жизненный цикл получателя

                      LocalBroadcastManager
http://goo.gl/2h80u
Контейнерная перевозка

Способ доставки:
  ● база данных (provider)

Проблемы:
  ● задержки
  ● "шторм" уведомлений




http://goo.gl/ZPoei
Из рук в руки

Способ доставки:
  ● singleton

Проблемы:
  ● один процесс
  ● расход памяти
  ● связанность



http://goo.gl/yfHPn   http://goo.gl/5AR9h
Заказное письмо

import android.os.ResultReceiver;
  private ResultReceiver receiver =
       new ResultReceiver(handler) {
         ...
       }
...
  new PollCommand(receiver)
       .start(...);

http://goo.gl/rwhw0
Зомби-дилемма

                 Receiver           Sender

 Activity                       Service




                Receiver           Sender
                                             onDestroy
 Activity                      Service




                    Receiver

     Activity
                Receiver            Sender
                                  Sender
                                             onCreate
Activity                       Service
Вечная жизнь
Application
                  Receiver

                                Sender

                             Service

  Activity




Application
                  Receiver

                                Sender

                             Service

  Activity
       Activity
Вечная жизнь: проблемы
Application
              Receiver

                            Sender
                 ?
                         Service

  Activity



                          Garbage
                          Collected
Application
              Receiver

                            Sender

                         Service

  Activity
Жизнь без проблем


Application                               Буфер

              Receiver


                                              Sender




                                    Service




        Activity
Плавность: UI Thread


private ResultReceiver receiver =
  new ResultReceiver(new Handler()) {
    ...
  }


      UI Thread!
Плавность: Background

private Handler handler =
  new Handler(handlerThread);

private ResultReceiver receiver =
  new ResultReceiver(handler) {
    ... onReceive(...) {
       ...
       runOnUiThread(...)
                                  UI
    }
  }
Плавность: всё вместе


private ResultReceiver receiverUi =
  new ResultReceiver(uiThrdHandler) {
    ...
  }

private ResultReceiver receiverBg =
  new ResultReceiver(bgThrdHandler) {
    ...
  }
Всё лучшее вместе
объединение разобщённых
Всё в одном



          GC
                      AIDL Binder

    Queue            get(id)
                 submit(id, command)
    Receiver

                Command
                   Command
Service
Выделение бизнес-
 логики в сервис
Дмитрий Викторович Малыханов

      Вопросы?
Выделение бизнес-
                      логики в сервис




The Android robot is reproduced or modified from work created and shared by Google and used according to terms described in the
Creative Commons 3.0 Attribution License.

UA Mobile 2012