进程间通信(IPC,Inter Process Communication)是指在不同进程之间传播或交换信息。
IPC方法包括管道(PIPE)、消息排队、旗语、共用内存以及套接字(Socket)!
进程之间的通讯是把两个不同的APK功能公开(通过接口),而contentProvider是把数据公开(通过Uri)
下面简单看一下进程的通讯:
定义提供服务的功能,可以看做是服务端
- 1、创建aidl文件(studio中选中包,右单击—>new —>AIDL,输入名称),填充功能方法
// IMusicInterface.aidl
package com.example.musicserver;
import com.example.musicserver.Music;
// Declare any non-default types here with import statements
interface IMusicInterface {
//对于AIDL声明中如果有引用类型需要添加in、inout、out的修饰
//in传入内容 out可以拿出内容(只针对引用类型) inout可以传入也可以传出(只针对引用类型)
void init(in List<Music> music);
void start(int index);
void pause();
}
如果有引用类型的参数,该类型必须序列化
public class Music implements Parcelable{
private String name;
private String path;
private int position;
...
}
添加aidl的描述(以music类为例,要创建Music.aidl,内容如下:)
parcelable Music;
- 2、定义服务,实现功能(在studio环境需要先build一下,aidl文件才会生成java代码)
public class MusicServer extends Service {
private List<Music> musics;
@Override
public IBinder onBind(Intent intent) {
return new MusicBinder();
}
//继承aidl生成java类中的Stub内部类
class MusicBinder extends IMusicInterface.Stub {
@Override
public void init(List<Music> music) throws RemoteException {
MusicServer.this.musics = music;
}
@Override
public void start(int index) throws RemoteException {
Log.e("m_tag", "start :" + musics.get(index).getName());
}
@Override
public void pause() throws RemoteException {
Log.e("m_tag", "pause :" );
}
}
}
功能使用端,可以看做为客户端
从服务端拷贝aidl生成的java代码(或者直接拷贝aidl文件)
- 1、绑定服务获取进程通讯的对象(aidl 生成的java接口的对象)
//操作服务端功能的对象
private IMusicInterface musicInterface;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
musicInterface = IMusicInterface.Stub.asInterface(service);
Log.e("m_tag","========onServiceConnected=========");
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
绑定服务:
Intent musicServerIntent = new Intent();
musicServerIntent.setClassName("com.example.musicserver", "com.example.musicserver.MusicServer");
bindService(musicServerIntent, conn, Context.BIND_AUTO_CREATE);
解绑服务
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
- 2、调用方法
List<Music> list = new ArrayList<>();
list.add(new Music("abc.mp3", "/mnt/sdcard/abc.mp3", 0));
list.add(new Music("hello.mp3", "/mnt/sdcard/hello.mp3", 10000));
if (musicInterface != null){
try {
musicInterface.init(list);
} catch (RemoteException e) {
e.printStackTrace();
}
}
if (musicInterface != null){
try {
musicInterface.start(1);
} catch (RemoteException e) {
e.printStackTrace();
}
}
通过Log可以看到结果: