Android 跨进程通信Messenger和AIDL

本文详细介绍了Android中的进程间通信(IPC)机制,包括AIDL和Messenger两种主要方式,并对比了它们的特点及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

进程间通信IPC

    IPC是 Inter-Proscess Communication的缩写,含义为进程间的通讯或者跨进程通讯,是指两个进程之间进行数据交换的过程。按操作系统的中的描述,线程是CPU调度最小的单元,同时线程是一种有限的系统资源,而进程是指一个执行单元,在PC和移动设备上指一个程序或者一个应用。一个进程可以包含多个线程,因此进程和线程是包含于被包含的关系。

为什么要使用多进程,一个进程所分配的内存有限,为了获取更大的内存,往往把一些耗内存的操作放到其他进程之中,往往把耗时操作放到不同线程之中,题外话:I/O操作为耗时操作,计算则为耗内存操作。

 

AIDL

    AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写,是多client且多线程的。

 

(1)新建一个AIDL文件

 

(2)在AIDL的接口文件中创建所需方法

interface IMyAIDL {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void addName();
    List<String> getNameList();
}

 

(3)编写服务端代码

public class ServeService extends Service{
    private List<String> names;
    private IBinder mIBinder = new IMyAIDL.Stub(){
        @Override
        public void addName(String name) throws RemoteException {
            names.add(name);
        }

        @Override
        public List<String> getNameList() throws RemoteException {
            return names;
        }
    };
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        names = new ArrayList<>();
        return mIBinder;
    }
}

 

(4)在客户端实现ServiceConnection接口,在这里拿到AIDL类

 

private IMyAIDL mAidl;

private ServiceConnection mConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //连接后拿到 Binder,转换成 AIDL,在不同进程会返回个代理
        mAidl = IMyAidl.Stub.asInterface(service);
    }

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

注意:在Manifests中把服务端Service放到其他进程中

   <service android:name=".ClientService"
            android:process="other"/>

 

(5)在客户端中绑定服务端Service

Intent intent = new Intent(getApplicationContext(), ServeService.class);
bindService(intent, mConnection, BIND_AUTO_CREATE);

 

(6)拿到AIDL类后,我们就可以通过调用AIDL中的方法来实现跨进程通信了

List<String> nameList = mAidl.getNameList();
mAidl.addName("张国荣");

 

Messenger

Messenger跨进程传递消息的机制和Handler类似,使用较为简单。使用Messenger的好处就是不用单独创建新的文件来传递消息。其底层实现和AIDL是一样的,且Messenger是一种较为轻量级的IPC方案。

(1)服务端代码

public class MessengerService extends Service {

    /**
     * 服务端Messenger
     */
    @SuppressLint("HandlerLeak")
    Messenger mMessenger = new Messenger(new Handler() {
        @Override
        public void handleMessage(final Message msg) {
            if (msg != null && msg.what == 1) {
                if (msg.getData() == null) {
                    return;
                }
                String content = (String) msg.getData().get("content");  //接收客户端的消息
                Log.d("cc", "Message from client: " + content);
                //回复消息给客户端
                Message replyMsg = Message.obtain();
                replyMsg.what = 2;
                Bundle bundle = new Bundle();
                bundle.putString("content", "收到了 over!");
                replyMsg.setData(bundle);
                try {
                    msg.replyTo.send(replyMsg);     //回信
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    });

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

 

(2)客户端代码

 

public class IPCTestActivity extends BaseActivity {
    //服务端的 Messenger
    private Messenger mServerMessenger;
    /**
     * 客户端的 Messenger
     */
    @SuppressLint("HandlerLeak")
    Messenger mClientMessenger = new Messenger(new Handler() {
        @Override
        public void handleMessage(final Message msg) {
            if (msg != null && msg.what == 2){
                if (msg.getData() == null){
                    return;
                }
                String content = (String) msg.getData().get("content");
                Log.d("cc", "message from service:"+content);
            }
        }
    });

    private ServiceConnection mMessengerConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(final ComponentName name, final IBinder service) {
            mServerMessenger = new Messenger(service);
        }

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

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindMessengerService();
    }

    /**
     * 绑定service
     */
    private void bindMessengerService() {
        Intent intent = new Intent(this, MessengerService.class);
        bindService(intent, mMessengerConnection, BIND_AUTO_CREATE);
        sendMsg();
    }

    /**
     * 客户端发送消息给service
     */
    public void sendMsg() {
        String msgContent ="我是客户端  收到请回话over!";
        Message message = Message.obtain();
        message.what = 1;
        Bundle bundle = new Bundle();
        bundle.putString("content", msgContent);
        message.setData(bundle);
        message.replyTo = mClientMessenger;     //指定回信人是客户端定义的

        try {
            mServerMessenger.send(message);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    /**
     * 销毁时解绑service
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mMessengerConnection);
    }

}

(3)回传消息(回信)

msg.replyTo.send(replyMsg);     //回信

msg.replyTo其实也是一个Messenger,它其实就是发送消息方的Messenger,在传递消息时它把本身也传递了过来,我们可以通过它来回传消息。

 

Messenger和AIDL的区别

    Messenger的本质其实也是AIDL只不过是进行了封装,Messenger只能用于传递数据,无法调用服务端的方法,而AIDL即可以传递数据也可以调用服务端方法,这也是Messenger和AIDL的本质区别。Messenger相较于AIDL更轻量级但是没有AIDL灵活,Messenger是以串行的方式处理客户端发来的消息,当消息多的时候就就不合适了,而AIDL是可以并发处理客户端传来的消息。根据不同情况我们需要选择不同解决办法。

 

跨进程通信的其他方法:

    Android实现跨进程通信其实还有很多其他的方法Content Provider,Broadcast,HermesEventBus(第三方开源库),文件共享,如果有需要可以了解一下。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值