binder 简介
Binder是Android提供的一套进程间相互通信框架。用来多进程间发送消息,同步和共享内存。
binder | 内存共享 | Socket | |
---|---|---|---|
性能 | 需要拷贝一次 | 无需拷贝 | 需要拷贝两次次 |
特点 | 基于C/S 架构,易用性高 | 控制复杂,易用性差 | 基于C/S 架构;作为一款通用接口,其传输效率低,开销大 |
安全性 | 为每个APP分配UID,同时支持实名和匿名。 | 依赖上层协议,访问接入点是开放的不安全 | 依赖上层协议,访问接入点是开放的不安全 |
内存被操作系统划分成两块:用户空间和内核空间,用户空间是用户程序代码运行的地方,内核空间是内核代码运行的地方。为了安全,它们是隔离的,即使用户的程序崩溃了,内核也不受影响。
传统IPC传送数据:1,发送数据。2、系统调用cocy_from_user()将数据从用户空间拷贝到内核空间。3、系统调用cocy_to_user()将数据从内核空间拷贝到用户空间。4’接收数据。
Binder传输数据:发送方通过系统调用cocy_from_user(),将数据从用户空间拷贝到内核空间。通过mmap,将内核空间的内存和接收方的一块内存同时映射到同一块物理空间中。这样就不需要第二次拷贝了。
Linux通过将一个虚拟内存区域与一个磁盘上的对象关联起来,以初始化这个虚拟内存区域的内容,这个过程称为内存映射(memory mapping)。
binder 使用
客户端
public class MainActivity extends Activity {
//iLeoAidl只是aidl通信的客户端Proxy对象。
private ILeoAidl iLeoAidl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
bindService();
}
private void initView() {
btn = (Button) findViewById(R.id.but_click);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
//点击按钮,通过调用aidl客户端的方法,通过binder通信调用到远程服务的方法。
iLeoAidl.addPerson(new Person("leo", 3));
List<Person> persons = iLeoAidl.getPersonList();
Log.e(TAG, persons.toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e(TAG, "onServiceConnected: success");
//绑定服务成功回到,将会返回远程的binder服务端。通过Stub的asInterface方法,将其封装到proxy中。
iLeoAidl = ILeoAidl.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e(TAG, "onServiceDisconnected: success");
iLeoAidl = null;
}
};
private void bindService() {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.xx.leo_service", "com.xx.leo_service.LeoAidlService"));
//绑定远程服务,传入connection对象。当服务被绑定后会回调connection对象的对应的方法。
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
//..。销毁后解绑服务。
}
public class Person implements Parcelable {
private String name;
private int grade;
//...
}
服务端
public class LeoAidlService extends Service {
private ArrayList<Person> persons;
//创建一个继承Stub的对象,实现用来通信的抽象方法。客户端调用对应方法后,最终就是调用这里的实现。
private IBinder iBinder = new ILeoAidl.Stub() {
@Override
public void addPerson(Person person) throws RemoteException {
persons.add(person);
}
@Override
public List<Person> getPersonList() throws RemoteException {
return persons;
}
};
@Override
public IBinder onBind(Intent intent) {
persons = new ArrayList<>();
//当接收到客户端绑定服务的请求后,会回到该方法。将上面创建好的Stub对象当IBinder成返回。
return iBinder;
}
@Override
public void onCreate() {
super.onCreate();
Log.e("LeoAidlService", "onCreate: success");
}
}
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a