Главная » Разработка для Android » Создание Сервисов и управление ими

0

В следующих разделах  вы узнаете, как создавать новые Сервисы, запу- скать и останавливать их, используя Намерения и метод startService. Позже научитесь привязывать Сервис к Активности, чтобы обеспечивать  более бо- гатый интерфейс для взаимодействия.

Создание Сервиса

Чтобы  получить  Cервис, создайте новый класс, который  будет потом- ком класса Service. Вам необходимо переопределить обработчики  onBind и onCreate, как показано в листинге 9.1.

Листинг 9.1. Каркас класса нового Сервиса

import android.app.Service;

import android.content.Intent;

Продолжение ?

Листинг 9.1 (продолжение)

import android.os.IBinder;

public class MyService extends Service {

@Override

public void onCreate() {

// TODO: действия, которые будут выполняться при создании сервиса.

}

@Override

public IBinder onBind(Intent intent) {

// TODO: Заменить реализацией привязки сервиса. return null;

}

}

В большинстве случаев, как правило, также необходимо переопределить метод onStartCommand. Он вызывается каждый раз, когда Сервис стартует с помощью метода startService, поэтому  может быть выполнен  несколь- ко раз на протяжении работы. Вы должны  убедиться,  что ваш Сервис это предусматривает.

Обработчик onStartCommand заменяет событие onStart, которое исполь- зовалось в Android 2.0. В отличие от onStart он позволяет  указать системе, каким образом обрабатывать перезапуски, если Сервис остановлен системой без явного вызова методов stopService или stopSelf.

Следующий фрагмент кода дополняет листинг 9.1 и демонстрирует каркас для переопределения обработчика onStartCommand. Обратите внимание, что от значения, которое он возвращает, зависит, как именно система прореагиру- ет на перезапуск Сервиса в случае принудительного завершения его работы.

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

// TODO Запустить поток в фоновом режиме для обработки. return Service.START_STICKY;

}

Сервисы  запускаются в главном  потоке приложения; это значит, что любые операции, выполняющиеся в обработчике  onStartCommand, будут работать в контексте  главного  потока GUI.  На практике  при реализации Сервиса в методе onStartCommand создают и запускают новый поток, что- бы выполнять операции  в фоновом режиме и останавливать Сервис, когда работа завершена  (далее  в этой главе вы узнаете, как создавать  фоновые потоки и управлять ими).

Такой  подход позволяет  методу onStartCommand быстро завершить работу и дает возможность контролировать поведение Сервиса при его по- вторном запуске, используя одну из констант.

START_STICKY. Описывает стандартное  поведение.  Похоже  на то, как был реализован метод onStart в Android 2.0. Если вы вернете

это значение,  обработчик  onStartCommand будет вызываться при повторном запуске Сервиса после преждевременного завершения работы. Обратите  внимание,  что аргумент  Intent, передаваемый в onStartCommand, получит значение null.

Данный режим обычно используется для Сервисов, которые сами об- рабатывают свои состояния, явно стартуя и завершая свою работу при необходимости (с помощью startService и stopService). Это относится к Сервисам, которые проигрывают  музыку или выполняют  другие за- дачи в фоновом режиме.

START_NOT_STICKY. Этот режим используется в Сервисах, которые запускаются для выполнения конкретных действий или команд. Как правило, такие Сервисы используют stopSelf для прекращения работы, как только команда выполнена.

После преждевременного прекращения работы Сервисы, работающие в данном режиме, повторно  запускаются только в том случае, если получат вызовы. Если с момента завершения работы Сервиса не был запущен  метод startService, он остановится без вызова обработчика onStartCommand.

Данный режим идеально подходит для Сервисов, которые обрабатыва- ют конкретные запросы, особенно это касается регулярного выполне- ния заданных действий (например, обновления или сетевые запросы). Вместо того, чтобы перезапускать Сервис при нехватке ресурсов, часто более целесообразно позволить ему остановиться и повторить попыт- ку запуска по прошествии запланированного интервала.

START_REDELIVER_INTENT. В некоторых случаях нужно убедить- ся, что команды, которые вы посылаете Сервису, выполнены.

Этот режим  — комбинация предыдущих  двух. Если  система  пре- ждевременно  завершила  работу Сервиса, он запустится повторно, но только когда будет сделан явный запрос на запуск или если процесс завершился до вызова метода stopSelf.

В последнем  случае вызовется обработчик  onStartCommand, он по- лучит первоначальное Намерение, обработка которого не завершилась должным образом.

Обратите  внимание, что при окончании  всех операций каждый из этих режимов требует явной остановки  Сервиса с помощью методов stopService или stopSelf. Оба эти метода подробнее описаны далее в этой главе.

ПРИМЕЧАНИЕ

В версиях, предшествующих Android SDK 2.0 (SDK API level 5), класс Service вызывал обработчик onStart, чтобы дать вам возможность выполнить какие-то действия при запуске Сервиса. Теперь же реа- лизация обработчика onStart эквивалентна переопределению метода onStartCommand, возвращающего флаг START_STICKY.

Режим  перезапуска,  который  вы указываете  в качестве значения,  воз- вращаемого  методом onStartCommand, будет влиять  на параметры,  пере- даваемые при последующих вызовах.

Изначально Намерение выступает в качестве параметра, который пере- дастся в метод startService при запуске Сервиса. После перезапуска системой он может иметь значение null (если установлен режим START_STICKY) или оригинальное (если установлен  флаг START_REDELIVER_INTENT).

Параметр  flag может помочь узнать, как именно  был запущен  Сервис. В частности, вы можете использовать фрагмент кода, показанный в листин- ге 9.2, чтобы определить, какая из констант соответствует  параметру flag:

START_FLAG_REDELIVERY — указывает на то, что параметр Intent повторно  передан при принудительном завершении работы Сервиса перед явным вызовом метода stopSelf;

START_FLAG_RETRY — указывает  на то, что Сервис повторно  за- пущен после непредвиденного завершения работы; передается в том случае, если ранее Сервис работал в режиме START_STICKY.

Листинг 9.2. Определение причины  запуска Сервиса системой

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

if ((flags & START_FLAG_RETRY) == 0) {

// TODO Если это повторный запуск, выполнить какие-то действия.

}

else {

// TODO Альтернативные действия в фоновом режиме.

}

return Service.START_STICKY;

}

Источник: Майер P. Android 2 : программирование приложений для планшетных компьютеров и смартфонов : [пер. с англ. ] / Рето Майер. — М. : Эксмо, 2011. — 672 с. — (Мировой компьютерный бестселлер).

По теме:

  • Комментарии