Binder机制原理的理解(方便以后自己回忆)

mac2025-04-05  21

Binder的由来

Linux内核有几种方式进程间通信

Socket :适用网络通信

共享内存 : 所有进程共享同一片

管道:半双工管道,就比如,A给B事件,跟B给A是二件事情,对讲机这样.

        全双工管道: A给B事件,跟B给A同时在一个方向传输,比如电话

管道通信: 开始创建A进程管道,A进程打开管道,然后B进程打开管道,进程A就会往管道里写数据  B进程在管道里读数.  结束后,进程A关闭管道,进程B也关闭管道,最后删除一个管道,消耗性能.

管道先会将数据进行每一次拷贝到内核空间,再将这些数据到目标第二个管道进程,二个复制过程

Binder: 对身份进行校检,安全,  还有性能相对好,只需要做一次通信. Androsid每安装一个APP就会为这个APP赋于一个UID,userId,是鉴别进程身份的唯一身份 PID进程ID.性能仅次于共享内存

 

Binder四个重要的角色

用户空间有:

Server :Client想要用Server ,Server 必须在ServiceManager中注册这个服务

Client  :他可以通过ServiceManager拿到Server中Binder实体的引用

ServiceManager  :相当于一个DNS服务器,是Server和Client的桥梁

内核空间(共享空间)有:

Binder驱动:负责进程之间Binder来通信的 Client Server ServiceManager都需要通过Binder驱动来进行通信,里面是有个线程池,一个进程的Binder线程数,默认是16,超过就堵塞等待空闲.

 

AIDL( Andoid Interface Definition Language )

IBinder:他是一个接口,代表跨进程通信的一种能力,只需要实现这个接口就可以跨进程传输

IInterface: 代表Server具备什么样的能力,提供的哪些方法

Binder: Java层的的Binder类,代表Binder的本地对象,如BinderProxy本地代理类

Client会先通过Binder驱动操作BinderProxy代理,BinderProxy一旦收到改变,就会copy_from_user到内核空间来,而Server在做校验的时候,拿到的key是不是我提供的binder对象,二者都是的就可以直接改变以Server端

Stub:  是AIDL工具自动生成的一个类,继承Binder实现了IInterface接口,抽象类

ANDROID有很多地方都用到了aidl,比如我们startActivity

他是通过ManagerService.getService获取到一个本地接口对象IActivityManager

public static IActivityManager getService() { return IActivityManagerSingleton.get(); } private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() { @Override protected IActivityManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };

ServiceManager.getService(Context.ACTIVITY_SERVICE) 这句代码可以获取到服务端对应的一个引用IBinder,

然后我们通过IActivityManager.Stub.asInterface(..)方法将IBinder传进去,就可能获取到一个代码对象IActivityManager.Proxy,并将IBinder赋值为mRemote

我们代理对象实现了IActivityManager接口,就走的是代理的IActivityManager.startActivity(...)

然后就开始通过Binder开始序列化数据为Parcel,并通过mRemote.transact方法将数据传输,就走到服务端的ActivityManagerService里面,因为ActivityManagerService是继承IActivityManager.Stub的而IActivityManager.Stub也实现了IActivityManager接口,所以ActivityManagerService需要重写IActivityManager所有的方法.

在IActivityManager.Stub.onTransact方法中会调用到this.startActivity,面这个this就是服务端的ActivityManagerService也就是ActivityManagerService.startActivity方法.

在ctivityManagerService.startActivity方法中,最后会走到ActivityStackSupervisor.realStartActivityLocked方法中,里面有几行关键代码

final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken); mService.getLifecycleManager().scheduleTransaction(clientTransaction);

 

分析下ClientTransaction.obtain(app.thread,r.appToken);这个方法

public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) { ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class); if (instance == null) { instance = new ClientTransaction(); } //2 instance.mClient = client; instance.mActivityToken = activityToken; return instance; }

在注解2中为ClientTransaction的成员变量mClient和mActivityToken赋值.而client是IApplicationThread是一个AIDL接口,所以肯定可以找到他的实现类也就是要继续他的IApplicationThread.Stub,面这个类就是ApplicationThread,是ActivityThread的一个内部类.所以当服务端处理完逻辑之后,又把之后要处理的逻辑交给了我们客户端

 

再来看看这行代码

mService.getLifecycleManager().scheduleTransaction(clientTransaction);

void scheduleTransaction(ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); transaction.schedule(); if (!(client instanceof Binder)) { // If client is not an instance of Binder - it's a remote call and at this point it is // safe to recycle the object. All objects used for local calls will be recycled after // the transaction is executed on client in ActivityThread. transaction.recycle(); } }

最后执行的是transaction.schedule();这个方法,也就在ClientTransation类里面的下面方法

public void schedule() throws RemoteException { mClient.scheduleTransaction(this); }

上面也分析了,mClient是AIDL的一个接口,可以实现进程间通讯,也就是直接从服务端来到了客户端也就是

ApplicationThread.scheduleTransaction(ClientTransaction transaction);

代码如下

@Override public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { ActivityThread.this.scheduleTransaction(transaction); }

上面代码中的ActivityThread.this就是ActivityThread也就是直接来到ActivityThread.scheduleTransation,而ActivityThread没有这个方法,但是可以在他的父类ClientTransactionHandler中找到,代码如下

void scheduleTransaction(ClientTransaction transaction) { transaction.preExecute(this); sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); }

也就是发送了一个消息出来,最后接收的肯定是在ActivityThread的mH的一个成员变量中

最后就会依次走上一个Activity的onPause,onStop 新Activity的onCreate onStart onResume 这些都是通过Handle来发送的

 

最新回复(0)