iremoteObject --------OpenHarmony中跨进程注册的observer 原创 精华

拓维信息流沙客
发布于 2022-4-26 17:54
浏览
10收藏

iremoteObject --------OpenHarmony中跨进程注册的observer

概述

一般来说,我们在编写代码的时候,经常遇到回调接口需要注册的情况,在单进程之中,我们经常是函数指针传给调用者。那跨进程的场景是如何操作的呢?答案就是iremoteObject。

以标准系统蓝牙代码为例

最近根据工作的要求,学习研究蓝牙相关代码。通过源码,我们理解学习了针对蓝牙服务,多事件监听的设计模式。

.
├── bluetooth_a2dp_sink_observer_proxy.h
├── bluetooth_a2dp_sink_observer_stub.h
├── bluetooth_a2dp_sink_proxy.h
├── bluetooth_a2dp_sink_stub.h
├── bluetooth_a2dp_src_observer_proxy.h
├── bluetooth_a2dp_src_observer_stub.h
├── bluetooth_a2dp_src_proxy.h
├── bluetooth_a2dp_src_stub.h
├── bluetooth_avrcp_ct_observer_proxy.h
├── bluetooth_avrcp_ct_observer_stub.h
├── bluetooth_avrcp_ct_proxy.h
├── bluetooth_avrcp_ct_stub.h
├── bluetooth_avrcp_tg_observer_proxy.h
├── bluetooth_avrcp_tg_observer_stub.h
├── bluetooth_avrcp_tg_proxy.h
├── bluetooth_avrcp_tg_stub.h
├── bluetooth_ble_advertise_callback_proxy.h
├── bluetooth_ble_advertise_callback_stub.h
├── bluetooth_ble_advertiser_proxy.h
├── bluetooth_ble_advertiser_stub.h
├── bluetooth_ble_central_manager_callback_proxy.h
├── bluetooth_ble_central_manager_callback_stub.h
├── bluetooth_ble_central_manager_proxy.h
├── bluetooth_ble_central_manager_stub.h
├── bluetooth_ble_peripheral_observer_proxy.h
├── bluetooth_ble_peripheral_observer_stub.h
├── bluetooth_gatt_client_callback_proxy.h
├── bluetooth_gatt_client_callback_stub.h
...

还是经典的proxy -stub架构。为了更好理解本文相关的内容,建议阅读 https://ost.51cto.com/posts/10765

我们截取其中的一部分来分析。

├── bluetooth_a2dp_sink_observer_proxy.h 
├── bluetooth_a2dp_sink_observer_stub.h
├── bluetooth_a2dp_sink_proxy.h
├── bluetooth_a2dp_sink_stub.h

咋一眼,和iremoteObject无关啊。a2dp是蓝牙音频传输的相关内容,sink是指的是控制端。这里我们不需要关注这个问题。我们还是通过源码看是如何跨进程注册的。

void BluetoothA2dpSinkProxy::RegisterObserver(const sptr<IBluetoothA2dpSinkObserver> &observer)
{
    MessageParcel data;
    if (!data.WriteInterfaceToken(BluetoothA2dpSinkProxy::GetDescriptor())) {
        HILOGE("BluetoothA2dpSinkProxy::RegisterObserver WriteInterfaceToken error");
        return;
    }
    if (!data.WriteRemoteObject(observer->AsObject())) { // 就是将对象进行传输
        HILOGE("BluetoothA2dpSinkProxy::RegisterObserver error");
        return;
    }

    MessageParcel reply;
    MessageOption option {
        MessageOption::TF_ASYNC
    };

    int error = Remote()->SendRequest(IBluetoothA2dpSink::Code::BT_A2DP_SINK_REGISTER_OBSERVER, data, reply, option);
    if (error != NO_ERROR) {
        HILOGE("BluetoothA2dpSinkProxy::RegisterObserver done fail, error: %{public}d", error);
        return;
    }
}

从上面可以看出 proxy通过写observer 对象到data中,然后再通过sendRequest发送到对端。那对端一般怎么做呢?对端一般是服务,也是真正的监听者 。到这里,其实我们也可以猜到个大概,使用std::bind转化对端发来的对象(或接口)注册到真正的事件监听中。(这个observer其实是对象也是接口,继承至iremoteBroker属于接口,继承至iremoteObject是对象。)

void BluetoothA2dpSinkServer::RegisterObserver(const sptr<IBluetoothA2dpSinkObserver> &observer)
{
    HILOGI("BluetoothA2dpSinkServer::RegisterObserver starts");
    if (observer == nullptr) {
        HILOGI("BluetoothA2dpSinkServer::RegisterObserver observer is null");
        return;
    }
    pimpl->observers_.Register(observer);
}

stub 中没有直接实现,他的子类BluetoothA2dpSinkServer去实现了。而真正的实现交给了pimpl->observers_它。

Observer真正触发

上文中说了半天,这个iremote对象注册了有什么用呢?当你的observer(proxy)注册到服务的(stub)中,服务中真正的触发了,被注册的observer(proxy),调用相关函数,sendRequest发送到proxy 中的stub中,触发真正的回调。 纵观整个过程通过binder驱动,发送消息,就好像observer注册到自身进程之中。

概述

一般来说,我们在编写代码的时候,经常遇到回调接口需要注册的情况,在单进程之中,我们经常是函数指针传给调用者。那跨进程的场景是如何操作的呢?答案就是iremoteObject。

以标准系统蓝牙代码为例

最近根据工作的要求,学习研究蓝牙相关代码。通过源码,我们理解学习了针对蓝牙服务,多事件监听的设计模式。

.
├── bluetooth_a2dp_sink_observer_proxy.h
├── bluetooth_a2dp_sink_observer_stub.h
├── bluetooth_a2dp_sink_proxy.h
├── bluetooth_a2dp_sink_stub.h
├── bluetooth_a2dp_src_observer_proxy.h
├── bluetooth_a2dp_src_observer_stub.h
├── bluetooth_a2dp_src_proxy.h
├── bluetooth_a2dp_src_stub.h
├── bluetooth_avrcp_ct_observer_proxy.h
├── bluetooth_avrcp_ct_observer_stub.h
├── bluetooth_avrcp_ct_proxy.h
├── bluetooth_avrcp_ct_stub.h
├── bluetooth_avrcp_tg_observer_proxy.h
├── bluetooth_avrcp_tg_observer_stub.h
├── bluetooth_avrcp_tg_proxy.h
├── bluetooth_avrcp_tg_stub.h
├── bluetooth_ble_advertise_callback_proxy.h
├── bluetooth_ble_advertise_callback_stub.h
├── bluetooth_ble_advertiser_proxy.h
├── bluetooth_ble_advertiser_stub.h
├── bluetooth_ble_central_manager_callback_proxy.h
├── bluetooth_ble_central_manager_callback_stub.h
├── bluetooth_ble_central_manager_proxy.h
├── bluetooth_ble_central_manager_stub.h
├── bluetooth_ble_peripheral_observer_proxy.h
├── bluetooth_ble_peripheral_observer_stub.h
├── bluetooth_gatt_client_callback_proxy.h
├── bluetooth_gatt_client_callback_stub.h
...

还是经典的proxy -stub架构。为了更好理解本文相关的内容,建议阅读 https://ost.51cto.com/posts/10765

我们截取其中的一部分来分析。

├── bluetooth_a2dp_sink_observer_proxy.h 
├── bluetooth_a2dp_sink_observer_stub.h
├── bluetooth_a2dp_sink_proxy.h
├── bluetooth_a2dp_sink_stub.h

咋一眼,和iremoteObject无关啊。a2dp是蓝牙音频传输的相关内容,sink是指的是控制端。这里我们不需要关注这个问题。我们还是通过源码看是如何跨进程注册的。

void BluetoothA2dpSinkProxy::RegisterObserver(const sptr<IBluetoothA2dpSinkObserver> &observer)
{
    MessageParcel data;
    if (!data.WriteInterfaceToken(BluetoothA2dpSinkProxy::GetDescriptor())) {
        HILOGE("BluetoothA2dpSinkProxy::RegisterObserver WriteInterfaceToken error");
        return;
    }
    if (!data.WriteRemoteObject(observer->AsObject())) { // 就是将对象进行传输
        HILOGE("BluetoothA2dpSinkProxy::RegisterObserver error");
        return;
    }

    MessageParcel reply;
    MessageOption option {
        MessageOption::TF_ASYNC
    };

    int error = Remote()->SendRequest(IBluetoothA2dpSink::Code::BT_A2DP_SINK_REGISTER_OBSERVER, data, reply, option);
    if (error != NO_ERROR) {
        HILOGE("BluetoothA2dpSinkProxy::RegisterObserver done fail, error: %{public}d", error);
        return;
    }
}

从上面可以看出 proxy通过写observer 对象到data中,然后再通过sendRequest发送到对端。那对端一般怎么做呢?对端一般是服务,也是真正的监听者 。到这里,其实我们也可以猜到个大概,使用std::bind转化对端发来的对象(或接口)注册到真正的事件监听中。(这个observer其实是对象也是接口,继承至iremoteBroker属于接口,继承至iremoteObject是对象。)

void BluetoothA2dpSinkServer::RegisterObserver(const sptr<IBluetoothA2dpSinkObserver> &observer)
{
    HILOGI("BluetoothA2dpSinkServer::RegisterObserver starts");
    if (observer == nullptr) {
        HILOGI("BluetoothA2dpSinkServer::RegisterObserver observer is null");
        return;
    }
    pimpl->observers_.Register(observer);
}

stub 中没有直接实现,他的子类BluetoothA2dpSinkServer去实现了。而真正的实现交给了pimpl->observers_它。

Observer真正触发

上文中说了半天,这个iremote对象注册了有什么用呢?当你的observer(proxy)注册到服务的(stub)中,服务中真正的触发了,被注册的observer(proxy),调用相关函数,sendRequest发送到proxy 中的stub中,触发真正的回调。 纵观整个过程通过binder驱动,发送消息,就好像observer注册到自身进程之中。

一图概览

iremoteObject --------OpenHarmony中跨进程注册的observer-鸿蒙开发者社区

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-12-26 15:05:50修改
9
收藏 10
回复
举报
3条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

感谢老师分享。

3
回复
2022-4-26 21:20:22
民之码农
民之码农

666

3
回复
2022-4-28 08:19:59
挖墙脚的农民工
挖墙脚的农民工

牛逼,大神之作

3
回复
2022-4-28 08:35:17
回复
    相关推荐