Android进程间通信小结

前言

今天把进程间通信的内容复习整理下,算是温故而知新吧。

小结目录

使用Bundle

我们通常在使用ActivityServiceReceiver的时候,都是支持在Intent中传递Bundle数据的,由于Bundle实现了Parcelable接口,所以它可以通过序列化与反序列化在多个进程之间进行传递数据。

<!--使用bundle方式-->
<activity android:name=".bundle.BundleXActivity" />
<activity android:name=".bundle.BundleYActivity"
          android:process=":bundle" />

如图所示

使用文件共享

共享文件说白了,就是多个进程通过读/写同一个文件来交换数据,但是由于基于Linux系统本身对并发读/写文件没有限制,因此并发读写容易出问题。例如:
多进程读写SharedPreferences就很容易出现脏数据

<!--使用file方式-->
<activity android:name=".file.FileXActivity" />
<activity android:name=".file.FileYActivity"
          android:process=":file" />

如图所示

使用Messenger通信

Messenger本身是基于AIDL实现的轻量级的IPC方案。

<!--使用Messenger方式-->
<activity android:name=".messenger.MessengerActivity" />
<service android:name=".messenger.MessengerService"
         android:process=":messenger"></service>

定义MessengerService服务端类

public class MessengerService extends Service {

    private static final String TAG = MessengerService.class.getSimpleName();

    private static class MsgHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case Constants.MSG_FROM_CLIENT:
                    ToastUtils.showLong("服务端收到: " + msg.getData().getString("message"));
                    break;
            }
            super.handleMessage(msg);
        }
    }

    private final Messenger mMessenger = new Messenger(new MsgHandler());

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

}

在绑定服务成功之后可以使用Messenger发送数据与服务端进行交互:

@Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mMessenger = new Messenger(service);
            Message msg = Message.obtain(null, Constants.MSG_FROM_CLIENT);
            Bundle bundle = new Bundle();
            bundle.putString("message", "Hello World!");
            msg.setData(bundle);
            try {
                mMessenger.send(msg);
            } catch (RemoteException e) {
                Log.e(TAG, "Send Message Exception...");
            }
        }

如图所示

使用AIDL方式

这种方式在实际生产中比较常见,使用AIDL进行进程间的通信其实比较简单:
1. 创建AIDL接口

// IMessage.aidl
package cn.byhook.ipc;

interface IMessage {

    String getMessage(int code);

}

然后点击Build/Make Module xxx

  1. 定义服务端
    跟上面的Messenger类似
public class IMessageService extends Service {

    private IMessage.Stub messageBinder = new IMessage.Stub() {
        @Override
        public String getMessage(int code) throws RemoteException {
            return "服务端收到: " + code;
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return messageBinder;
    }
}
  1. 定义客户端
    绑定成功之后即可交互数据
private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mMessage = IMessage.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

这种方式在实际生产过程中很常见

使用ContentProvider方式

ContentProvider是系统中提供的专门用于不同应用进程间进行数据共享的一种方式,所以在系统中很常见,我们平时读取系统的短信等操作,就会使用到ContentResolver来进行操作读取。

<!--使用ContentProvider方式-->
        <activity android:name=".provider.ProviderActivity" />
        <provider
            android:name=".provider.MessageProvider"
            android:authorities="cn.byhook.ipc.provider"
            android:permission="cn.byhook.ipc.permission"
            android:process=":provider" />

将Provider和Activity置于不同的进程中,具体代码就不贴了,可以参考下面的例子

小结地址:
https://github.com/byhook/ipc-sample

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值