DEV_EASY_NOTES Telegram 60
Второй способ взаимодействовать с сервисом на другом процессе это AIDL.

👉 AIDL или Android Interface Definition Language, это язык, который позволяет нам описывать интерфейсы межпроцессного общения. Язык чем-то похож на урезанную java с некоторыми интересными ключевыми словами.

🙌 Суть в чем, описываем в интерфейсе те функции какие мы хотим вызывать на другом процессе, а также входные аргументы и тип результата. Пример того, как может выглядеть этот интерфейс:
// ICalculator.aidl
interface ICalculator {
int sum(int first, int second);
}

В простых примерах синтаксис вообще не отличается от java (кстати заметили ублюдский🤬 префикс "I" будто мы в C#, в AIDL по-прежнему используется этот пережиток прошлого). После того как мы написали интерфейс, компилятор генерирует классы Proxy и Stub.

Proxy – то, что использует клиент, чтобы вызывать функции другого процесса так, будто они находятся в одном процессе.
Stub – использует сервис, или по другому сервис теперь должен реализовать методы, которые мы определили в интерфейсе.

Проще будет понять на примере, сервис будет выглядеть так:

override fun onBind(intent: Intent?): IBinder {
return object : ICalculator.Stub() {
override fun sum(first: Int, second: Int): Int {
return first + second
}
}
}

На стороне клиента мы должны теперь получить Proxy, делаем мы это через байндинг этого сервиса и уже сгенеренных методов ICalculator:

val intent = Intent(this, CalculatorMessengerService::class.java)
bindService(intent, object : ServiceConnection {

override fun onServiceDisconnected(name: ComponentName?) = Unit

override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val proxy = ICalculator.Stub.asInterface(service)
val sum = proxy.sum(1, 4)
}
}, BIND_AUTO_CREATE)


На этом все, теперь можно напряму вызывать методы другого процесса.

Proxy делает "маршалинг" (Marshalling), т.е перегоняет аргументы функций в последовательность байт. Stub соответственно делает "анмаршалинг" (Unmarshaling), перегоняет поток байт обратно в объекты, которые описаны в AIDL.

🤓 Еще раз пройдемся по всем компонентам которые у нас есть, советую параллельно смотреть в картинку.
У каждого Binder есть Token, по сути это просто некоторый desriptor, который помогает системе понять что это конкретно за реализация Binder. Если заглянуть в метод sum, который сгенерирован в proxy, мы увидим что там первой строчкой при маршалинге будет:

_data.writeInterfaceToken(DESCRIPTOR);

Эта строчка означает, что когда мы передаем массив байт в Stub, первые байты будут нести информацию о самом Binder.

Интерфейс IBinder это интерфейс, который описывает методы нужные для межпроцессной коммуникации. Binder стандартная реализация интерфейса IBinder, в Binder реализованы все сложные методы коммуникации и который мы можем расширять, чтобы использовать. Stub наследует Binder и нам остается только реализовать те методы которые мы указали в AIDL. Proxy использует объект IBinder, просто передать данные в Stub.

И теперь представь 🌈, все Intent, ContentProvider, все сервисы которые мы получаем через getSystemService() - все это работает через Binder и AIDL, круто не правда ли?

🎉 Если ты дочитал до сюда и примерно сможешь это пересказать, то я тебя поздравляю ты охренеть какая умничка и теперь сможешь выпендится на собесе. Тема очень сложная и используется только на очень больших проектах которым мало одного процесса или в каких-нибудь SDK, как например Яндекс.Метрика. 

В посте было очень много упрощений, чтобы не делать его супер большим, если тебе понравилась тема стоит посмотреть этот доклад, который расскажет все это, но подробнее.
🔥10



tgoop.com/dev_easy_notes/60
Create:
Last Update:

Второй способ взаимодействовать с сервисом на другом процессе это AIDL.

👉 AIDL или Android Interface Definition Language, это язык, который позволяет нам описывать интерфейсы межпроцессного общения. Язык чем-то похож на урезанную java с некоторыми интересными ключевыми словами.

🙌 Суть в чем, описываем в интерфейсе те функции какие мы хотим вызывать на другом процессе, а также входные аргументы и тип результата. Пример того, как может выглядеть этот интерфейс:
// ICalculator.aidl
interface ICalculator {
int sum(int first, int second);
}

В простых примерах синтаксис вообще не отличается от java (кстати заметили ублюдский🤬 префикс "I" будто мы в C#, в AIDL по-прежнему используется этот пережиток прошлого). После того как мы написали интерфейс, компилятор генерирует классы Proxy и Stub.

Proxy – то, что использует клиент, чтобы вызывать функции другого процесса так, будто они находятся в одном процессе.
Stub – использует сервис, или по другому сервис теперь должен реализовать методы, которые мы определили в интерфейсе.

Проще будет понять на примере, сервис будет выглядеть так:

override fun onBind(intent: Intent?): IBinder {
return object : ICalculator.Stub() {
override fun sum(first: Int, second: Int): Int {
return first + second
}
}
}

На стороне клиента мы должны теперь получить Proxy, делаем мы это через байндинг этого сервиса и уже сгенеренных методов ICalculator:

val intent = Intent(this, CalculatorMessengerService::class.java)
bindService(intent, object : ServiceConnection {

override fun onServiceDisconnected(name: ComponentName?) = Unit

override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val proxy = ICalculator.Stub.asInterface(service)
val sum = proxy.sum(1, 4)
}
}, BIND_AUTO_CREATE)


На этом все, теперь можно напряму вызывать методы другого процесса.

Proxy делает "маршалинг" (Marshalling), т.е перегоняет аргументы функций в последовательность байт. Stub соответственно делает "анмаршалинг" (Unmarshaling), перегоняет поток байт обратно в объекты, которые описаны в AIDL.

🤓 Еще раз пройдемся по всем компонентам которые у нас есть, советую параллельно смотреть в картинку.
У каждого Binder есть Token, по сути это просто некоторый desriptor, который помогает системе понять что это конкретно за реализация Binder. Если заглянуть в метод sum, который сгенерирован в proxy, мы увидим что там первой строчкой при маршалинге будет:

_data.writeInterfaceToken(DESCRIPTOR);

Эта строчка означает, что когда мы передаем массив байт в Stub, первые байты будут нести информацию о самом Binder.

Интерфейс IBinder это интерфейс, который описывает методы нужные для межпроцессной коммуникации. Binder стандартная реализация интерфейса IBinder, в Binder реализованы все сложные методы коммуникации и который мы можем расширять, чтобы использовать. Stub наследует Binder и нам остается только реализовать те методы которые мы указали в AIDL. Proxy использует объект IBinder, просто передать данные в Stub.

И теперь представь 🌈, все Intent, ContentProvider, все сервисы которые мы получаем через getSystemService() - все это работает через Binder и AIDL, круто не правда ли?

🎉 Если ты дочитал до сюда и примерно сможешь это пересказать, то я тебя поздравляю ты охренеть какая умничка и теперь сможешь выпендится на собесе. Тема очень сложная и используется только на очень больших проектах которым мало одного процесса или в каких-нибудь SDK, как например Яндекс.Метрика. 

В посте было очень много упрощений, чтобы не делать его супер большим, если тебе понравилась тема стоит посмотреть этот доклад, который расскажет все это, но подробнее.

BY Dev Easy Notes


Share with your friend now:
tgoop.com/dev_easy_notes/60

View MORE
Open in Telegram


Telegram News

Date: |

6How to manage your Telegram channel? How to Create a Private or Public Channel on Telegram? Some Telegram Channels content management tips ZDNET RECOMMENDS During a meeting with the president of the Supreme Electoral Court (TSE) on June 6, Telegram's Vice President Ilya Perekopsky announced the initiatives. According to the executive, Brazil is the first country in the world where Telegram is introducing the features, which could be expanded to other countries facing threats to democracy through the dissemination of false content.
from us


Telegram Dev Easy Notes
FROM American