You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android IPC中AIDL与Messenger双向通信:服务端向客户端传参咨询

Android IPC:服务端向客户端传输数据实现方案

不管是AIDL还是Messenger,双向通信的核心都是让服务端持有客户端的通信入口,从而主动发起数据传输。以下是两种方式的具体实现:

一、AIDL实现服务端向客户端推送数据

AIDL通过回调接口实现服务端到客户端的通信,步骤如下:

1. 定义回调AIDL接口

新建IClientCallback.aidl文件,声明服务端调用客户端的方法:

package com.example.ipcdemo;

interface IClientCallback {
    void onDataReceived(String serverData);
}

2. 修改主AIDL接口,添加回调注册/注销方法

在你的主AIDL(比如IServerAidlInterface.aidl)中,新增管理回调的方法:

package com.example.ipcdemo;

import com.example.ipcdemo.IClientCallback;

interface IServerAidlInterface {
    // 客户端向服务端发数据的方法
    void sendDataToServer(String clientData);
    // 注册客户端回调
    void registerCallback(IClientCallback callback);
    // 注销客户端回调
    void unregisterCallback(IClientCallback callback);
}

3. 服务端实现AIDL接口,维护回调列表

服务端使用RemoteCallbackList来管理跨进程回调(避免内存泄漏和线程安全问题),在需要时主动调用客户端的回调方法:

public class ServerService extends Service {
    private final RemoteCallbackList<IClientCallback> mCallbackList = new RemoteCallbackList<>();

    private final IServerAidlInterface.Stub mBinder = new IServerAidlInterface.Stub() {
        @Override
        public void sendDataToServer(String clientData) throws RemoteException {
            // 处理客户端发来的数据
        }

        @Override
        public void registerCallback(IClientCallback callback) throws RemoteException {
            if (callback != null) {
                mCallbackList.register(callback);
            }
        }

        @Override
        public void unregisterCallback(IClientCallback callback) throws RemoteException {
            if (callback != null) {
                mCallbackList.unregister(callback);
            }
        }
    };

    // 模拟服务端主动向客户端推送数据
    private void pushDataToClients() {
        int count = mCallbackList.beginBroadcast();
        for (int i = 0; i < count; i++) {
            try {
                mCallbackList.getBroadcastItem(i).onDataReceived("来自服务端的推送数据");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        mCallbackList.finishBroadcast();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

4. 客户端实现回调接口,注册到服务端

客户端绑定服务后,实现IClientCallback.Stub,并注册到服务端,即可接收服务端的推送:

public class ClientActivity extends AppCompatActivity {
    private IServerAidlInterface mServer;
    private IClientCallback mCallback = new IClientCallback.Stub() {
        @Override
        public void onDataReceived(String serverData) throws RemoteException {
            // 收到服务端数据,更新UI需切换到主线程
            runOnUiThread(() -> {
                // 处理服务端发来的数据
            });
        }
    };

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mServer = IServerAidlInterface.Stub.asInterface(service);
            try {
                // 注册回调到服务端
                mServer.registerCallback(mCallback);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mServer = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_client);
        // 绑定服务端服务
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.example.serverapp", "com.example.serverapp.ServerService"));
        bindService(intent, mConnection, BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mServer != null) {
            try {
                mServer.unregisterCallback(mCallback);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        unbindService(mConnection);
    }
}

二、Messenger实现服务端向客户端推送数据

Messenger基于Handler和Message实现,通过replyTo字段传递客户端Messenger,让服务端能反向发送消息:

1. 客户端创建自己的Messenger和Handler

客户端实现Handler处理服务端发来的消息,并创建对应的Messenger:

public class ClientActivity extends AppCompatActivity {
    private Messenger mServerMessenger;
    // 客户端的Messenger,用于接收服务端消息
    private Messenger mClientMessenger = new Messenger(new ClientHandler());

    private static class ClientHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                // 获取服务端发来的数据
                String serverData = msg.getData().getString("server_data");
                // 处理数据
            }
        }
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mServerMessenger = new Messenger(service);
            // 向服务端发送消息,并携带客户端的Messenger
            Message msg = Message.obtain(null, 0);
            msg.replyTo = mClientMessenger;
            Bundle bundle = new Bundle();
            bundle.putString("client_data", "客户端初始数据");
            msg.setData(bundle);
            try {
                mServerMessenger.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mServerMessenger = null;
        }
    };

    // 绑定服务逻辑同AIDL客户端,此处省略
}

2. 服务端保存客户端的Messenger,主动发送数据

服务端收到客户端消息后,取出replyTo保存,之后通过这个Messenger向客户端发消息:

public class ServerService extends Service {
    private Messenger mClientMessenger;

    private Messenger mServerMessenger = new Messenger(new ServerHandler());

    private static class ServerHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.what == 0) {
                // 获取客户端数据
                String clientData = msg.getData().getString("client_data");
                // 保存客户端的Messenger,用于反向通信
                mClientMessenger = msg.replyTo;
                // 模拟服务端主动推送数据
                sendDataToClient();
            }
        }
    }

    private void sendDataToClient() {
        if (mClientMessenger != null) {
            Message msg = Message.obtain(null, 1);
            Bundle bundle = new Bundle();
            bundle.putString("server_data", "来自服务端的推送数据");
            msg.setData(bundle);
            try {
                mClientMessenger.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mServerMessenger.getBinder();
    }
}

为什么称AIDL和Messenger是双向通信?

因为这两种方式下,客户端和服务端都持有对方的通信通道:

  • AIDL中,服务端通过客户端注册的回调接口调用客户端方法;客户端通过服务端的Binder调用服务端方法。
  • Messenger中,服务端通过客户端传递的replyTo Messenger发送消息;客户端通过服务端的Messenger发送消息。
    双方都能主动发起数据传输,因此属于双向通信。

内容的提问来源于stack exchange,提问作者Nikhil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 20:06:19