Jacky's blog
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)
  • tutorial
  • jetpack

  • components

  • androidx

  • 动态化
  • apm

  • module

  • harmony

  • tool

  • other

    • Flutter 高频面试问答
    • 生产环境Message分发处理设计
    • 事件分发机制
    • 调研抖音对harmonyOS4的优化
    • Android 评论at功能的实现
    • 探索抖音禁止录屏
    • 对32位手机崩溃的优化记录
    • GradientDrawable
    • android window
    • color
    • webview白屏检测
    • android Resource
    • deeplink技术
    • android-xml
    • ANDROID IPC
      • 通信方式
      • binder
      • other
        • RemoteCallbackList
      • link
    • BottomSheetBehavior研究与思考
    • viewPager
    • Android密钥系统
    • compiler
    • 提升UI加载速度的几点思考
    • Android零耗时首帧体验
    • jsbridge
    • retrofit动态代理设计
    • gif与属性动画的对比
  • kotlin

  • 《android》
  • other
Jacky
2024-12-27
目录

ANDROID IPC

# 通信方式

  1. bundle
  2. 使用文件共享
  3. Messenger
  4. AIDL
  5. ContentProvider
  6. Socket

# binder

# other

# RemoteCallbackList

RemoteCallbackList 是 Android 中的一个类,它提供了一种线程安全的方式来管理和调用远程回调接口。这个类通常用于在服务端与多个客户端之间传递回调对象,特别是在 AIDL (Android Interface Definition Language) 的远程通信场景下,它可以帮助服务端向多个客户端发送回调信息。

RemoteCallbackList 的基本介绍

RemoteCallbackList 是 Android 提供的一个特殊的 线程安全 集合类,用于存储远程回调对象(通常是实现了 IBinder 接口的对象)。它允许服务端在回调函数中向多个客户端发送通知,并且提供了一些内置的方法来管理回调对象的生命周期。

这个类的核心功能包括:

  1. 存储回调对象: 用于存储多个回调接口,通常是实现了 IInterface 接口的对象,如 IServiceCallback。
  2. 线程安全: 使得回调的调用和管理可以在多线程环境下安全进行。
  3. 清理回调: RemoteCallbackList 自动管理回调对象的注册和注销,并在回调失效时及时清理对象。
  4. 批量回调: 它支持在一个批量操作中将消息或事件通知给多个回调对象。
RemoteCallbackList 的主要方法

以下是 RemoteCallbackList 常用的一些方法:

  1. add(callback: T)

    • 向 RemoteCallbackList 中添加一个回调对象。
    • 参数 callback 通常是一个实现了 IBinder 接口的回调对象。
  2. remove(callback: T)

    • 从 RemoteCallbackList 中移除指定的回调对象。
  3. beginBroadcast()

    • 在调用回调时,首先需要调用此方法,表示即将开始向所有回调对象发送广播。这是线程安全的,可以防止在遍历回调时发生竞争条件。
  4. finishBroadcast()

    • 在回调操作完成后调用此方法,表示回调的广播已经结束。
  5. getRegisteredCallbackCount()

    • 获取当前 RemoteCallbackList 中注册的回调对象数量。
  6. getCallbackItem(index: Int)

    • 获取 RemoteCallbackList 中指定索引位置的回调对象。
  7. clear()

    • 清除 RemoteCallbackList 中的所有回调对象。
  8. hasCallbacks()

    • 检查 RemoteCallbackList 是否有任何回调对象。
使用场景

RemoteCallbackList 类的使用通常与 AIDL 服务相关,尤其是在客户端需要接收服务端的异步回调时。服务端可能会向多个客户端发送回调,而 RemoteCallbackList 用来安全地管理这些回调并通知客户端。

一个典型的使用场景示例

假设你有一个 IServiceCallback 接口,它用于从服务端向客户端传递更新,服务端将使用 RemoteCallbackList 来管理多个客户端的回调。

  1. 定义回调接口
public interface IServiceCallback extends IInterface {
    void onUpdate(String data) throws RemoteException;
}
1
2
3
  1. 创建服务端实现
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
  1. 客户端实现
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
注意事项
  1. 线程安全:

    • RemoteCallbackList 是线程安全的,可以在多个线程中安全地注册、注销和回调。调用 beginBroadcast() 和 finishBroadcast() 可以确保在遍历回调时不会发生竞争条件。
  2. 回调的生命周期管理:

    • 服务端通过 RemoteCallbackList 来管理回调对象的生命周期。当回调对象发生异常或被客户端移除时,它会自动从列表中清除,避免内存泄漏。
  3. 远程服务和 AIDL:

    • RemoteCallbackList 适用于远程服务(如使用 AIDL 的服务),用于解决服务和客户端之间异步回调的问题。它在 IBinder 对象之间传递数据时非常有用。

# link

- <https://github.com/jacky1234/IPCDemo>
上次更新: 2025/07/17, 17:31:43
android-xml
BottomSheetBehavior研究与思考

← android-xml BottomSheetBehavior研究与思考→

最近更新
01
npx 使用指南
10-12
02
cursor
09-28
03
inspect
07-20
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式