Здравствуйте друзья,

В этом блоге мы собираемся углубиться в связанные сервисы Android. Связанная служба имеет следующие характеристики:

  • Это сервер в клиент-серверном интерфейсе.
  • Это позволяет таким компонентам, как действия/фрагменты, привязываться к службе.
  • Компоненты, привязанные к службе, могут отправлять запросы, получать ответы и выполнять IPC [межпроцессное взаимодействие].

Связанная служба напрямую зависит от связанного с ней компонента; то есть, пока он выполняет некоторые операции для связанной службы, он продолжает работать. После этого он автоматически завершается.

Следовательно, он не работает в фоновом режиме бесконечно.

На следующем изображении указаны обратные вызовы жизненного цикла связанной службы:

Создание связанной службы:

Связанную службу можно создать, предоставив IBinder, который предоставляет программный интерфейс, который клиенты могут использовать для взаимодействия со службой. Есть три способа определить интерфейс:

  1. Расширение класса Binder
  2. Использование мессенджера
  3. Использование AIDL (язык определения интерфейса Android)

В этом блоге мы сосредоточимся только на реализации Binder. Вот определение класса службы с реализацией AudioLoopServiceBinder для Binder().

IBinder:

Чтобы создать связанную службу, мы должны определить интерфейс, указывающий, как клиент может взаимодействовать со службой. Этот интерфейс между службой и клиентом должен быть реализацией IBinder, и это то, что ваша служба должна возвращать из метода обратного вызова onBind().

После того, как клиент получит IBinder, он может начать взаимодействовать со службой через этот интерфейс.

Не забудьте добавить запись службы в AndroidManifest.xml.

<service android:name="com.alokomkar.service.AudioLoopBoundService" />

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

Мы бы завершили нашу реализацию, обновив класс HomeFragment.

Кроме того, мы будем отслеживать, связана ли служба или нет, поместив переменную в класс HomeViewModel, как показано ниже:

Флаг, определенный в HomeViewModel, переключается в определенном объектеboundServiceConnection:

private val boundServiceConnection by lazy {
    object : ServiceConnection {
        override fun onServiceConnected(className: ComponentName, service: IBinder) {
            val binder: AudioLoopBoundService.AudioLoopServiceBinder = service as AudioLoopBoundService.AudioLoopServiceBinder
            audioLoopBoundService = binder.getService()
            viewModel.isAudioServiceBound = true // bound here
        }

        override fun onServiceDisconnected(arg0: ComponentName) {
            audioLoopBoundService?.runAction(ServiceAction.STOP_ACTION)
            audioLoopBoundService = null
            viewModel.isAudioServiceBound = false // unbound here
        }
    }
}

Мы бы привязали службу в onStart() :

override fun onStart() {
    super.onStart()
    // bind to service if it isn't bound
    if (!viewModel.isAudioServiceBound) bindToAudioService()
}

Не забудьте отвязать службу в onDestroy() :

override fun onDestroy() {
    super.onDestroy()
    unbindAudioService()
}

Службу можно запускать и останавливать с помощью кнопок, определенных в файле home_fragment.xml.

<androidx.appcompat.widget.AppCompatButton
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/start_playback_bound"
    android:layout_margin="@dimen/default_margin"
    android:id="@+id/startButtonBoundService"/>

<androidx.appcompat.widget.AppCompatButton
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/stop_playback_bound"
    android:layout_margin="@dimen/default_margin"
    android:id="@+id/stopButtonBoundService"/>

На этом все, спасибо за прочтение.