1.什么是Binder
Binder 是一种进程间通信机制,基于开源的 OpenBinder 实现;OpenBinder 起初由 Be Inc. 开发,后由 Plam Inc. 接手。从字面上来解释 Binder 有胶水、粘合剂的意思,顾名思义就是粘和不同的进程,使之实现通信。
2.什么时候需要用到进程间通信?
Android开发者们都知道,Android 应用程序是由 Activity、Service、Broadcast Receiver 和 Content Provide 四大组件中的一个或者多个组成的。然而有时这些组件运行在同一进程,有时运行在不同的进程。这些进程间的通信就依赖于 Binder IPC 机制。Android 系统对应用层提供的各种服务如:ActivityManagerService、PackageManagerService 等都是基于 Binder IPC 机制来实现的。还有就是支付宝纳入海量应用、大型登入架构的实现等等。由此可见Binder 机制在 Android 中的位置非常重要。
3.进程间通信为什么要用到Binder机制?
Android 系统是基于 Linux 内核的,Linux 已经提供了共享内存和 Socket 等 IPC 机制。那为什么 Android 还要提供 Binder 来实现 IPC 呢?
Binder通信与其他通信的区别如下图:
4. 进程间通信原理
在Android系统中每一个进程的用户空间(User Space)都是隔离的,进程1没有办法直接访问进程2的数据,这也就是所谓的进程隔离,但是内核空间(Kernal Space)是共享的。当进程1发起系统调用时(Binder实现IPC通信),进行一个复制数据到内核空间的缓存区,再通过mmap的映射关系,就相当于把数据发送到了接收进程的用户空间,这样便完成了一次进程间的通信。(整个过程就是一个数据copy和一个内存数据映射过程)
4.Biner通信机制的简单实现(AIDL)
通常我们在开发时,实现进程间通信的最多可能就是AIDL了,当我在AS中定义好我们的.AIDL文件,AS就会给我们直接生成对应的实现IPC通信的.java文件,因此帮助我们进一步了解IPC通信机制。
IBinder : IBinder 是一个接口,代表了一种跨进程通信的能力。只要实现了这个借口,这个对象就能跨进程传输。
IInterface : IInterface 代表的就是 Server 进程对象具备什么样的能力(能提供哪些方法,其实对应的就是 AIDL 文件中定义的接口)
Binder : Java 层的 Binder 类,代表的其实就是 Binder 本地对象。BinderProxy 类是 Binder 类的一个内部类,它代表远程进程的 Binder 对象的本地代理;这两个类都继承自 IBinder, 因而都具有跨进程传输的能力;实际上,在跨越进程的时候,Binder 驱动会自动完成这两个对象的转换。
Stub : AIDL 的时候,编译工具会给我们生成一个名为 Stub 的静态内部类;这个类继承了 Binder, 说明它是一个 Binder 本地对象,它实现了 IInterface 接口,表明它具有 Server 承诺给 Client 的能力;Stub 是一个抽象类,具体的 IInterface 的相关实现需要开发者自己实现。
4.1.AS自动生成的代码
package com.drsports;
/**
* @author Vson
* 项目描述:这个是客户端AIDL自动生成的,里面有注释过程
*/
public interface IMyAidlInterface extends android.os.IInterface {
...
/**
* Local-side IPC implementation stub class.
*/
public static abstract class Stub extends android.os.Binder implements IMyAidlInterface {
//描述符
private static final java.lang.String DESCRIPTOR = "IMyAidlInterface";
/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
//挂载接口
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an IMyAidlInterface interface,
* generating a proxy if needed.
* *将一个IBinder对象转换成com.drsports.server.IMyAidlInterface接口,
* *如果需要,生成代理。(动态代理)
*/
public static IMyAidlInterface asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof IMyAidlInterface))) {
//查看是否本地接口,如果是本地接口,直接返回
return ((IMyAidlInterface) iin);
}
//如果不是本地接口,远程获取一个接口(句柄)
return new IMyAidlInterface.Stub.Proxy(obj);
}
...
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
//这个是远程的Server,因为客户端和服务端的代码是一个的,为了节省空间就是贴出来
java.lang.String descriptor = DESCRIPTOR;
switch (code) {
...
case TRANSACTION_addPerson: {
...
//调用继承类的addPerson(_arg0)方法,也就是
//AidlService中的new IMyAidlInterface.Stub()
this.addPerson(_arg0);
reply.writeNoException();
return true;
}
....
}
}
private static class Proxy implements IMyAidlInterface {
//内部对象
public static IMyAidlInterface sDefaultImpl;
//发送数据(远程IBinder)
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
//获取远程IBinder
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
//获取描述符
return DESCRIPTOR;
}
@Override
public void addPerson(com.drsports.server.Person person) throws android.os.RemoteException {
//客户端发送数据
android.os.Parcel _data = android.os.Parcel.obtain();
//服务端返回数据
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
//C层校验数据
_data.writeInterfaceToken(DESCRIPTOR);
if ((person != null)) {
_data.writeInt(1);
person.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
//调用服务端方法,将客服端挂起,直到服务端返回数据
//flags 是0表示客户端和服务端相互通信;是1表示客户端只能发送,服务端不能返回数据
//Stub.TRANSACTION_addPerson方法ID
boolean _status = mRemote.transact(Stub.TRANSACTION_addPerson, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
getDefaultImpl().addPerson(person);
return;
}
//读取异常
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
.....
}
static final int TRANSACTION_addPerson = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getPersonList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
...
4.2.客户调用代码
/**
* onAIDLServer点击事件
*
* @param view
*/
public void onAIDLServer(View view) {
try {
//使用服务句柄调用服务方法,完成IPC通行
myAidlInterface.addPerson(new Person("vson", 2));
List mList = myAidlInterface.getPersonList();
Log.d("sss", mList.toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
private IMyAidlInterface myAidlInterface;
private ServiceConnection connection2 = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获取服务句柄
myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
myAidlInterface = null;
}
};
//进入页面时调用完成bind代码
public void myBindService() {
Intent intent = new Intent();
//服务端通过反射创建的Service
remoteServer = new ComponentName("com.drsports.server", "com.drsports.server.AidlService");
intent.setComponent(remoteServer);
bindService(intent, connection2, Service.BIND_AUTO_CREATE);
}
4.3.服务端代码
package com.drsports.server;
/**
* @author vson
*/
public class AidlService extends Service {
private ArrayList mList;
@Nullable
@Override
public IBinder onBind(Intent intent) {
mList = new ArrayList<>();
return binder;
}
private IBinder binder = new IMyAidlInterface.Stub() {
@Override
public void addPerson(Person person) throws RemoteException {
Log.d("TAG", person.toString());
mList.add(person);
}
@Override
public List getPersonList() throws RemoteException {
return mList;
}
};
}
当客户端调用bindService时,系统层代码会调用connection2中的onServiceConnected实现一次服务绑定,而在onServiceConnected中,通过IMyAidlInterface.Stub.asInterface(service)获取服务端的server句柄,这个过程是动态代理的过程。接下来当客户端调用 myAidlInterface.addPerson(new Person("vson", 2)),是调用实现IMyAidlInterface接口的Proxy中的addPerson方法,其中 mRemote.transact()方法就是内核层使用Binder调用远程Server的onTransact()方法。在Server端中的AIDL中有一个this.addPerson()方法其实是调用Stub的实现类的addPerson方法,也就是上面服务端代码new IMyAidlInterface.Stub() 的addPerson()方法。
5.Biner通信机制的源码分析(API23中bindService实现)
当客户端调用bindServer方法时,进入了Context的装饰类ContextWrapper中,但是真正实现bindServer方法的是Context的实现类ContextImpl:
public class ContextWrapper extends Context {
...
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}
...
}
class ContextImpl extends Context {
...
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, Process.myUserHandle());
}
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
UserHandle user) {
IServiceConnection sd;
...
if (mPackageInfo != null) {
//ServiceConnection的接口回调的封装
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
mMainThread.getHandler(), flags);
}
...
// ActivityManagerNative.getDefault() 返回就相当于AIDL的proxy
//而这个Proxy就是ActivityManagerService类
int res = ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
...
}
//ActivityManagerNative==>Stub
public abstract class ActivityManagerNative extends Binder implements IActivityManager{
/**
* Cast a Binder object into an activity manager interface, generating
* a proxy if needed.
*/
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
/**
* Retrieve the system's default/global activity manager.
*/
static public IActivityManager getDefault() {
//返回Binder 的proxy
return gDefault.get();
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case BIND_SERVICE_TRANSACTION: {
...
IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
//调用真正的服务(启动服务)ActivityManagerService
int res = bindService(app, token, service, resolvedType, conn, fl,
callingPackage, userId);
...
}
}
private static final Singleton gDefault = new Singleton(){
protected IActivityManager create() {
//IBiner就是AMS服务,这个是系统启动时添加进去的
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
//获取远程服务句柄
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
}
//ActivityManagerProxy ===>proxy
class ActivityManagerProxy implements IActivityManager{
...
public ActivityManagerProxy(IBinder remote)
{
mRemote = remote;
}
public int bindService(IApplicationThread caller, IBinder token,
Intent service, String resolvedType, IServiceConnection connection,
int flags, String callingPackage, int userId) throws RemoteException {
....
//进行远程调用服务方法
mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
...
}
...
}
public interface IActivityManager extends IInterface {}
有上面的代码可以看出:bindServer过程是调用ContextImpl的bindSever方法进而调用了bindServiceCommon方法,bindServiceCommon方法中调用了ActivityManagerNative.getDefault().bindService方法,可以看出ActivityManagerNative.getDefault()返回的IActivityManager就相当与AIDL中实现 IMyAidlInterface的Proxy,而这个Proxy就是ActivityManagerService类;而ActivityManagerNative.getDefault().bindService()就是相当于Proxy.bindService();IActivityManager继承IInterface接口,所以IActivityManager就相当于AIDL接口IMyAidlInterface ;可以看出ActivityManagerNative和ActivityManagerProxy就是相当于Stub和Proxy的关系。
整理如下图:
接下来我在看ActivityManagerService这个类:
public final class ActivityManagerService extends ActivityManagerNative{
...
public int bindService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String callingPackage,
int userId) throws TransactionTooLargeException {
enforceNotIsolatedCaller("bindService");
....
synchronized(this) {
//同步处理(枷锁)
//mServices是ActiveServices
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, callingPackage, userId);
}
}
...
}
public final class ActiveServices {
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags,
String callingPackage, int userId) throws TransactionTooLargeException {
...
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
//>1.进程B,整个进程都没有启动
//>2.进程B启动了,但是里面的Service没有创建出来
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
return 0;
}
}
...
if (b.intent.apps.size() == 1 && b.intent.doRebind) {
//重新bind服务
//1.进程B启动了,里面的Service也创建了,但是Service没有绑定过,回调onBind()
//2.进程B启动了,里面的Service也创建了,但是Service已经绑定过,回调onRebind()
requestServiceBindingLocked(s, b.intent, callerFg, true);
} else if (!b.intent.requested) {
//没有bind服务
//1.进程B启动了,里面的Service也创建了,但是Service没有绑定过,回调onBind()
//2.进程B启动了,里面的Service也创建了,但是Service已经绑定过,回调onRebind()
requestServiceBindingLocked(s, b.intent, callerFg, false);
}
}
private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting) throws TransactionTooLargeException {
...
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
ProcessRecord app;
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (app != null && app.thread != null) {
//>1.进程B,整个进程都没有启动
//>2.进程B启动了,但是里面的Service没有创建出来
//B进程已成启动了
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
realStartServiceLocked(r, app, execInFg);
return null;
}
}
}
...
return null;
}
}
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
...
//ProcessRecord是一个进程记录,ProcessRecord.thread指向的是ActivityThread.ApplicationThread
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
...
}
public final class ActivityThread {
...
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
//这里是Handler消息
sendMessage(H.CREATE_SERVICE, s);
}
public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
updateProcessState(processState, false);
BindServiceData s = new BindServiceData();
s.token = token;
s.intent = intent;
s.rebind = rebind;
//这里是Handler消息
sendMessage(H.BIND_SERVICE, s);
}
public void handleMessage(Message msg) {
...
case CREATE_SERVICE:
handleCreateService((CreateServiceData)msg.obj);
break;
..
}
//真正创建服务的方法
private void handleCreateService(CreateServiceData data){
//使用类加载器加载Service
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
....
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
//服务挂载参数
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
//服务的生命周期onCreate方法回调
service.onCreate();
//存储服务,如果再次创建就从这个获取
mServices.put(data.token, service);
...
}
...
}
A进程访问B进程时几种状态
1.bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null)
1.进程B,整个进程都没有启动
2.进程B启动了,但是里面的Service没有创建出来
2.requestServiceBindingLocked(s, b.intent, callerFg, false);
1.进程B启动了,里面的Service也创建了,但是Service没有绑定过,回调onBind()
2.进程B启动了,里面的Service也创建了,但是Service已经绑定过,回调onRebind()