【Android】源码之 RemoteCallbackList

前言

最近在替换蓝牙方案商的时候,发现其在使用 RemoteCallbackList 进行回调。于是抱着学习的心态来看看这个类吧。

在 Android 中,RemoteCallbackList 类是一个用于跨进程通信的工具类,可以用来注册、注销和通知客户端的回调接口。它在 Android 系统中广泛应用于各种系统服务和框架组件中,如通知服务、Activity 生命周期回调、媒体播放器等等。

什么是 RemoteCallbackList

RemoteCallbackList 是一个类似于列表的数据结构,它用于存储回调接口对象。每个回调接口对象都有一个唯一的 Binder 标识符,可以用来在不同进程之间进行传递和跟踪。RemoteCallbackList 的主要功能是提供了一组安全的 API,使得客户端可以注册、注销和通知回调接口对象,同时还提供了一些线程安全的方法,保证了并发操作的正确性。

RemoteCallbackList 的使用

在使用 RemoteCallbackList 时,我们通常需要实现一个 Binder 服务或者一个 AIDL 接口,并在其中创建一个 RemoteCallbackList 对象。这个对象会被用来存储客户端注册的回调接口对象。

以下是 RemoteCallbackList 的常用方法:

register(T callback):注册一个回调接口对象。
unregister(T callback):注销一个回调接口对象。
beginBroadcast():开始通知客户端,返回客户端数量。
getBroadcastItem(int index):获取指定位置的回调接口对象。
finishBroadcast():通知客户端结束。

以下是一个简单的例子:

public class MyBinder extends Binder {
    private RemoteCallbackList<MyCallback> mCallbacks = new RemoteCallbackList<>();

    public void registerCallback(MyCallback callback) {
        mCallbacks.register(callback);
    }

    public void unregisterCallback(MyCallback callback) {
        mCallbacks.unregister(callback);
    }

    public void notifyCallbacks(String message) {
        int count = mCallbacks.beginBroadcast();
        for (int i = 0; i < count; i++) {
            try {
                mCallbacks.getBroadcastItem(i).onMessageReceived(message);
            } catch (RemoteException e) {
                // do nothing
            }
        }
        mCallbacks.finishBroadcast();
    }
}

在上面的例子中,我们创建了一个名为 MyBinder 的 Binder 服务,并在其中使用了 RemoteCallbackList 来实现注册、注销和通知回调接口对象。当客户端调用 registerCallback 方法时,会将回调接口对象添加到 RemoteCallbackList 中;当客户端调用 unregisterCallback 方法时,会将回调接口对象从 RemoteCallbackList 中移除;当服务端需要通知客户端时,会调用 notifyCallbacks 方法,遍历 RemoteCallbackList 中所有的回调接口对象,并调用其相应的方法,实现回调的功能。

RemoteCallbackList 的线程安全性

由于 RemoteCallbackList 可能会被多个线程同时访问,因此其线程安全性非常重要。RemoteCallbackList 内部使用了一些同步机制,保证了其并发操作的正确性。

具体来说,RemoteCallbackList 内部维护了两个不同的列表:一个是注册的回调接口列表,另一个是正在通知的回调接口列表。当客户端注册或注销回调接口对象时,会先获取锁,然后将操作同步到注册的回调接口列表中。而当服务端需要通知客户端时,也会获取锁,然后将正在通知的回调接口列表设置为注册的回调接口列表的副本,以确保通知期间注册和注销回调接口对象不会影响到正在通知的列表。

此外,RemoteCallbackList 还提供了一些线程安全的方法,如 beginBroadcast、getBroadcastItem 和 finishBroadcast,这些方法在操作期间会获取锁,保证了并发操作的正确性。
总结

RemoteCallbackList 类是 Android 框架中的一个重要工具类,用于跨进程通信中的回调接口处理。它提供了一组安全的 API,使得客户端可以注册、注销和通知回调接口对象,并提供了一些线程安全的方法,保证了并发操作的正确性。在实际开发中,我们通常需要在 Binder 服务或者 AIDL 接口中使用 RemoteCallbackList,以实现回调接口对象的注册、注销和通知。

你可能感兴趣的:(Android,android)