ANDROID IPC
# 通信方式
- bundle
- 使用文件共享
- Messenger
- AIDL
- ContentProvider
- Socket
# binder
# other
# RemoteCallbackList
RemoteCallbackList 是 Android 中的一个类,它提供了一种线程安全的方式来管理和调用远程回调接口。这个类通常用于在服务端与多个客户端之间传递回调对象,特别是在 AIDL (Android Interface Definition Language) 的远程通信场景下,它可以帮助服务端向多个客户端发送回调信息。
RemoteCallbackList 的基本介绍RemoteCallbackList 是 Android 提供的一个特殊的 线程安全 集合类,用于存储远程回调对象(通常是实现了 IBinder 接口的对象)。它允许服务端在回调函数中向多个客户端发送通知,并且提供了一些内置的方法来管理回调对象的生命周期。
这个类的核心功能包括:
- 存储回调对象: 用于存储多个回调接口,通常是实现了 IInterface 接口的对象,如 IServiceCallback。
- 线程安全: 使得回调的调用和管理可以在多线程环境下安全进行。
- 清理回调: RemoteCallbackList 自动管理回调对象的注册和注销,并在回调失效时及时清理对象。
- 批量回调: 它支持在一个批量操作中将消息或事件通知给多个回调对象。
以下是 RemoteCallbackList 常用的一些方法:
add(callback: T)- 向 RemoteCallbackList 中添加一个回调对象。
- 参数 callback 通常是一个实现了 IBinder 接口的回调对象。
remove(callback: T)- 从 RemoteCallbackList 中移除指定的回调对象。
beginBroadcast()- 在调用回调时,首先需要调用此方法,表示即将开始向所有回调对象发送广播。这是线程安全的,可以防止在遍历回调时发生竞争条件。
finishBroadcast()- 在回调操作完成后调用此方法,表示回调的广播已经结束。
getRegisteredCallbackCount()- 获取当前 RemoteCallbackList 中注册的回调对象数量。
getCallbackItem(index: Int)- 获取 RemoteCallbackList 中指定索引位置的回调对象。
clear()- 清除 RemoteCallbackList 中的所有回调对象。
hasCallbacks()- 检查 RemoteCallbackList 是否有任何回调对象。
RemoteCallbackList 类的使用通常与 AIDL 服务相关,尤其是在客户端需要接收服务端的异步回调时。服务端可能会向多个客户端发送回调,而 RemoteCallbackList 用来安全地管理这些回调并通知客户端。
一个典型的使用场景示例假设你有一个 IServiceCallback 接口,它用于从服务端向客户端传递更新,服务端将使用 RemoteCallbackList 来管理多个客户端的回调。
- 定义回调接口
public interface IServiceCallback extends IInterface {
void onUpdate(String data) throws RemoteException;
}
1
2
3
2
3
- 创建服务端实现
public class MyService extends Service {
// 创建一个 RemoteCallbackList
private final RemoteCallbackList<IServiceCallback> mCallbacks = new RemoteCallbackList<>();
@Override
public IBinder onBind(Intent intent) {
return new IService.Stub() {
@Override
public void registerCallback(IServiceCallback callback) {
mCallbacks.register(callback); // 注册回调
}
@Override
public void unregisterCallback(IServiceCallback callback) {
mCallbacks.unregister(callback); // 注销回调
}
@Override
public void sendUpdate(String data) {
int numCallbacks = mCallbacks.beginBroadcast(); // 开始广播
for (int i = 0; i < numCallbacks; i++) {
try {
mCallbacks.getBroadcastItem(i).onUpdate(data); // 向每个回调发送更新
} catch (RemoteException e) {
e.printStackTrace();
}
}
mCallbacks.finishBroadcast(); // 广播完成
}
};
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- 客户端实现
public class MyActivity extends Activity {
private IService mService;
private IServiceCallback mCallback = new IServiceCallback.Stub() {
@Override
public void onUpdate(String data) throws RemoteException {
// 处理回调数据
Log.d("MyActivity", "Received update: " + data);
}
};
@Override
protected void onStart() {
super.onStart();
// 绑定服务
bindService(new Intent(this, MyService.class), mConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IService.Stub.asInterface(service);
try {
mService.registerCallback(mCallback); // 注册回调
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
try {
mService.unregisterCallback(mCallback); // 注销回调
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
线程安全:
- RemoteCallbackList 是线程安全的,可以在多个线程中安全地注册、注销和回调。调用
beginBroadcast()和finishBroadcast()可以确保在遍历回调时不会发生竞争条件。
- RemoteCallbackList 是线程安全的,可以在多个线程中安全地注册、注销和回调。调用
回调的生命周期管理:
- 服务端通过 RemoteCallbackList 来管理回调对象的生命周期。当回调对象发生异常或被客户端移除时,它会自动从列表中清除,避免内存泄漏。
远程服务和 AIDL:
- RemoteCallbackList 适用于远程服务(如使用 AIDL 的服务),用于解决服务和客户端之间异步回调的问题。它在 IBinder 对象之间传递数据时非常有用。
# link
- <https://github.com/jacky1234/IPCDemo>上次更新: 2025/07/17, 17:31:43