👉 Все из вас кто хоть когда-то залазил в класс Service в Android должны были заметить, что там есть метод onBind() который возвращает объект IBinder. В большинстве случаев мы просто забиваем и возвращаем null, но ведь этот метод там явно не просто так, да еще и интерфейс так называется IBinder, прям в тему, смекаете😉? Чтобы сделать Bound Service, необходимо определить класс, унаследованный от класса Binder и определить в нем некоторую логику которая будет исполняться на сервисе. Например, что-то вроде:
class CalculatorService : Service() {
override fun onBind(intent: Intent?): IBinder = Calculator()
class Calculator : Binder() {
fun sum(first: Int, second: Int): Int = first + second
}
}
Затем нужно запустить этот сервис через специальный метод контекста bindService(). Когда сервис подключится к нашей Activity вызовется callback onServiceConnected() у объекта ServiceConnection. После чего мы приводим входной аргумент IBinder к нашему конкретному классу и можем напрямую вызывать методы сервиса из нашей Activity:
val intent = Intent(this, CalculatorService::class.java)
bindService(intent, object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val calculator = service as CalculatorService.Calculator
val result = calculator.sum(1, 2)
}
override fun onServiceDisconnected(name: ComponentName?) = Unit
}, BIND_AUTO_CREATE)
Это все, теперь можно сделать межпроцессное общение❓
Неа😄 это работает только в том случае, если и Service и Activity работают в одном процессе.
Тогда для чего такие сложности и зачем это нужно❓
🤷 По большей части если речь идет о выполнении в одном процессе оно и правда может быть лишним, так как данные можно передавать и через data слой посредством например RxJava.
Нам сейчас это нужно для понимания того, как работает Binder. Ведь для общения между двумя процессами, нужно лишь слегка исправить наш пример. А что конкретно нужно исправить, обсудим в следующем посте📝