Сервер AIDL
Нарешті, ми можемо створити сервер, який надаватиме сервіс:
birthday_service/src/server.rs:
//! Сервіс привітання з днем народження.
use birthdayservice::BirthdayService;
use com_example_birthdayservice::aidl::com::example::birthdayservice::IBirthdayService::BnBirthdayService;
use com_example_birthdayservice::binder;
const SERVICE_IDENTIFIER: &str = "birthdayservice";
/// Точка входу для сервісу дня народження.
fn main() {
let birthday_service = BirthdayService;
let birthday_service_binder = BnBirthdayService::new_binder(
birthday_service,
binder::BinderFeatures::default(),
);
binder::add_service(SERVICE_IDENTIFIER, birthday_service_binder.as_binder())
.expect("Не вдалося зареєструвати сервіс");
binder::ProcessState::join_thread_pool()
}
birthday_service/Android.bp:
rust_binary {
name: "birthday_server",
crate_name: "birthday_server",
srcs: ["src/server.rs"],
rustlibs: [
"com.example.birthdayservice-rust",
"libbinder_rs",
"libbirthdayservice",
],
prefer_rlib: true, // Щоб уникнути помилки динамічного лінкування.
}
Процес створення користувацької реалізації сервісу (у цьому випадку типу BirthdayService
, який реалізує IBirthdayService
) і запуску його як сервісу Binder складається з кількох кроків і може здатися складнішим, ніж ті, хто звик до Binder з C++ або іншої мови. Поясніть учням, чому кожен крок є необхідним.
- Створіть екземпляр вашого типу сервісу (
BirthdayService
). - Оберніть об'єкт сервісу у відповідний тип
Bn*
(у цьому випадкуBnBirthdayService
). Цей тип генерується Binder і надає загальну функціональність Binder, яку надавав би базовий класBnBinder
у C++. У Rust немає успадкування, тому замість нього ми використаємо композицію, помістивши нашBirthdayService
всередину згенерованогоBnBinderService
. - Викликаемо
add_service
, передавши йому ідентифікатор сервісу і ваш об'єкт сервісу (у прикладі - об'єктBnBirthdayService
). - Викликаемо
join_thread_pool
щоб додати поточний потік до пулу потоків Binder'а і починаємо чекати на з'єднання.