Android IPC方式解读

Android IPC方式解读

1.使用Bundle

由于Bundle实现了Parcelable接口,所以它可以很方便在进程之间进行传输。四大组件中的三大组件都支持在intent中传递Bundle数据的。

2.使用文件共享

共享文件也是一种进程间实现数据传输的方式,两个进程读写同一个文件就可以实现,Android是基于Linux的,所有对文件的读写可以没有限制的进行,这就可能会造成一些错误,但是通过这种方式交换数据非常简单,通过文件共享方式来交换数据是没有文件格式的要求的,只要通信双方约定好同样的格式进行转换即可。文件共享方式的局限性在于高并发情况下的读写有可能会出现问题,文件共享方式适合在对数据同步性要求不高的场景下使用。

3.使用Messenger

Messenger翻译为信使,通过它可以在不同的进程之间传递Message对象,在Message中放入我们需要传递的数据,这样可以轻松的实现数据在进程间的交换,Messenger是一种轻量级的IPC方案,他的底层实现AIDL。实现一个Messenger有以下几步分为服务端和客户端:

第一步:首先我们需要在服务端创建一个Service来处理客户端的连接请求,同时创建一个Handler,并用这个Handler创建一个Messenger对象。在onBind方法中,将Messenger底层的Binder返回。

第二步:客户端中,首先要绑定服务,绑定成功以后,利用服务器端返回的IBinder对象创建一个Messenger,通过这个Messenger就可以向服务端发送信息了,发送的消息类型为Message对象。

public class MessengerService extends Service {
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case 1:
                    String message = msg.getData().getString("data");
                    Log.d("MessengerService", "handleMessage: "+message);
                    break;
            }
        }
    };
    private Messenger messenger = new Messenger(handler);


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

public class MainActivity  extends AppCompatActivity {
    private final String Tag = "MainActivity";
    private Messenger messenger;
    ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            messenger = new Messenger(service);
            Message message = new Message();
            message.what=1;
            Bundle data = new Bundle();
            data.putString("data", "你好,我是客户端");
            message.setData(data);
            try {
                messenger.send(message);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent();
        intent.setClass(MainActivity.this, MessengerService.class);
        bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(serviceConnection);
    }
}

从上述的案例中可以看出,在Messenger中传递数据必须要通过Message。Message和Messenger都实现了Parcelabel接口,当我们需要传递对象的时候,可以通过Bundle。这个例子演示了服务器端接受客户端发来的信息,有时候我们还需要服务器端能够回复客户端,下面我们来实现具有回复功能的,代码只需要略作修改即可。


public class MessengerService extends Service {
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case 1:
                    String message = msg.getData().getString("data");
                    Log.d("MessengerService", "handleMessage: "+message);
                    Messenger messenger = msg.replyTo;
                    Message reply = new Message();
                    reply.what=1;
                    Bundle bundle = new Bundle();
                    bundle.putString("reply", "你的消息我已经收到,我是服务器端");
                    reply.setData(bundle);
                    try {
                        messenger.send(reply);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
            }
        }
    };
    private Messenger messenger = new Messenger(handler);


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


public class MainActivity  extends AppCompatActivity {
    private final String Tag = "MainActivity";
    private Messenger messenger;

    private Handler replyHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case 1:
                    String message = msg.getData().getString("reply");
                    Log.d("MessengerService", "handleMessage: "+message);
                    break;
            }
        }
    };
    private Messenger replyMessenger=new Messenger(replyHandler);
    ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            messenger = new Messenger(service);
            Message message = new Message();
            message.what=1;
            Bundle data = new Bundle();
            data.putString("data", "你好,我是客户端");
            message.setData(data);
            message.replyTo=replyMessenger;
            try {
                messenger.send(message);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent();
        intent.setClass(MainActivity.this, MessengerService.class);
        bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(serviceConnection);
    }
}

在这里插入图片描述
Messenger的工作流程如下:
在这里插入图片描述

4.使用AIDL

上面我们介绍的Messenger也有一点缺点,只能串行的处理数据,如果有大量的消息发送到服务器端,只能一条一条处理,如果有大量的并发请求,那么就不合适了。很多时候我们还可能需要调用服务器端的方法,但是Messenger只能用来传递数据。这种情况下,我们使用AIDL,下面介绍AIDL怎么实现进程间的通信,分为服务器端和客户端两个方面。

1.服务器端
需要创建一个Service用来监听客户端的请求,然后创建一个AIDL,将暴露给客户端的方法在其中声明,并在Service中实现该AIDL接口。

2.客户端
客户端端首先要绑定服务,绑定成功以后,将服务器端的Binder转换成AIDL接口所对应的类型即可,接着就可以调用AIDL中的方法了。

具体请看实现请看另外一篇博客
一个简单的AIDL实例

5.ContentProvider

6.Scoket

使用Scoket实现多进程通信方法比较简单,实现方式请查看我的这篇博客
Socket通信

猜你喜欢

转载自blog.csdn.net/weixin_43927892/article/details/105451374