Binder 是什么? 作者的个人理解
1.对于系统来说,Binder 类似于血管,链接这ServiceMananger ActivityManagerService ActivityTaskManagerService,承载着他们之间的信息的传递
2.对于kernel 底层来说,binder 是驱动,是一种虚拟的底层驱动
3.对于Java 应用层来说,他是一个封装了一套序列化的 Clint 与 Service 信息交互类
想要了解Binder 就不得不从AIDL 说起, AIDL 为我们封装了一套标准的 Clint 与 Service 端的交互方式,我们如何来使用它交互呢,先看一下 简单的AIDL 的编译后的类的结构
我们来看一下为什么说AIDL是一套 Clint/Service 交互方式呢
image.png简单的创建了一个AIDL 的 interface
使用这个文件编译后的 文件目录大体是下面这个样子
public interface IMyAidlInterface extends android.os.IInterface
{
/** Default implementation for IMyAidlInterface. */
public static class Default implements com.example.myservice.IMyAidlInterface
{
@Override public void say() throws android.os.RemoteException
{
}
@Override public java.lang.String getStringContent() throws android.os.RemoteException
{
return null;
}
@Override
public android.os.IBinder asBinder() {
return null;
}
}
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.example.myservice.IMyAidlInterface
{
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
public static com.example.myservice.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.myservice.IMyAidlInterface))) {
return ((com.example.myservice.IMyAidlInterface)iin);
}
return new com.example.myservice.IMyAidlInterface.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
private static class Proxy implements com.example.myservice.IMyAidlInterface
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
public static com.example.myservice.IMyAidlInterface sDefaultImpl;
}
public static com.example.myservice.IMyAidlInterface getDefaultImpl() {
return Stub.Proxy.sDefaultImpl;
}
}
}
image.png
现在思考一个问题,为什么Clint 拿道的是一个Proxy ,Service 交出的是一个Stub 呢,他们两个为什么不能拿到同一个对象吗,那样使用起来多方便,这个里面就存在一个问题,由于进程是隔离,这就让他们同时持有一个对象变得不可能,此时就有另外一个说法,能不能为两个APP 进程开辟同一个系统的内核空间呢,这样两面只要操作内核空间就可以了,其实这种方案也有一个弊端,那就是一端在写的同时,另一端来读数据,这就造成了数据混乱或者就是脏数据,最后就形成了现在的Binder 的这种使用代理的通信机制,
通过代码来看一下他们的依赖关系是什么
Clint 端
我们在BinderService 的过程中都会传入一个ServiceConncetion 对象,在bind成功后会调用 AIDLInterface.Stub.asInterface 来获取 AIDL Interface.Stub.Proxy 的示例
private ServiceConnection serviceConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyAidlInterface binder = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
在Interface.Stub 中做了一下判断,传进来是是否是IInterface,不是就创建一个Proxy
public static com.example.myservice.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.myservice.IMyAidlInterface))) {
return ((com.example.myservice.IMyAidlInterface)iin);
}
return new com.example.myservice.IMyAidlInterface.Stub.Proxy(obj);
}
上面就是Clint 端建立链接的过程
Service 端
public class MyService extends Service {
private final IMyAidlInterface.Stub binder=new IMyAidlInterface.Stub() {
@Override
public void say() throws RemoteException {
}
@Override
public String getStringContent() throws RemoteException {
return "Hellow";
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
}
service 端在内部创建了一个IInterface 的Stub ,在onBind的时候将这个 stub 对外提供,来做数据通信
整个过程看起来很简单,那么对于Android 系统来说,SystemServer 是如何来调度和管理各个 IInterface 的呢,我们就以ActivityTaskManagerService一个为例
App 启动过程
App启动的过程是通过zygote fork 出来的,具体的过程就是调用 ZygoteIntent.forkSystemService 方法复制出来的,具体的代码如下
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
fork 出app进程后,启动流程就在SystemServer中了,在SystemServer 的Run 方法内 做了3个特别重要的方法
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
其中 startBootstrapServices 这个方法中就初始化了 ActivityTaskManagerService,我们来看一下代码
// Activity manager runs the show.
t.traceBegin("StartActivityManager");
// TODO: Might need to move after migration to WM.
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService(); //启动atms
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm); // 启动AMS
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mWindowManagerGlobalLock = atm.getGlobalLock();
t.traceEnd();
可以看到启动的是 mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class),我们继续来看SystemServiceManager 的startService
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
// Create the service.
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
}
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service constructor threw an exception", ex);
}
startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
SystemServiceManager 通过类对象使用反射创建一个实例,在将这个service实例添加到 mService 这个SystemService 的list 当中,并执行ActivityTaskManagerService.Lifecycle的onStart 方法
ActivityTaskManagerService.Lifecycle 继承自SystemService
public static final class Lifecycle extends SystemService {
private final ActivityTaskManagerService mService;
public Lifecycle(Context context) {
super(context);
mService = new ActivityTaskManagerService(context);
}
@Override
public void onStart() {
publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
mService.start();
}
@Override
public void onUserUnlocked(@NonNull TargetUser user) {
synchronized (mService.getGlobalLock()) {
mService.mTaskSupervisor.onUserUnlocked(user.getUserIdentifier());
}
}
@Override
public void onUserStopped(@NonNull TargetUser user) {
synchronized (mService.getGlobalLock()) {
mService.mTaskSupervisor.mLaunchParamsPersister
.onCleanupUser(user.getUserIdentifier());
}
}
public ActivityTaskManagerService getService() {
return mService;
}
}
在 ActivityTaskManagerService.Lifecycle 的onstart 方法中,将一个在ActivityTaskManagerService.Lifecycle 初始化过程中创建ActivityTaskManagerService 的mService 放入到了SystemService publishBinderService,
我们先来看一下 ActivityTaskManagerService 这个类的继承关系
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
可以看到他就是一个aidl 中的一个服务端的Stub 代理类,我们继续向下看 SystemServcie 的publishBinderService方法
protected final void publishBinderService(@NonNull String name, @NonNull IBinder service) {
publishBinderService(name, service, false);
}
/**
* Publish the service so it is accessible to other services and apps.
*
* @param name the name of the new service
* @param service the service object
* @param allowIsolated set to true to allow isolated sandboxed processes
* to access this service
*/
protected final void publishBinderService(@NonNull String name, @NonNull IBinder service,
boolean allowIsolated) {
publishBinderService(name, service, allowIsolated, DUMP_FLAG_PRIORITY_DEFAULT);
}
protected final void publishBinderService(String name, IBinder service,
boolean allowIsolated, int dumpPriority) {
ServiceManager.addService(name, service, allowIsolated, dumpPriority);
}
在这个方法里面将这个 service 放入到了ServiceManager 中,继续向下看
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;//ServiceManagerProxy
}
public static void addService(String name, IBinder service, boolean allowIsolated,
int dumpPriority) {
try {
getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
这个里面就是获取到了一个 IServiceManager 的 IInterface Stub 的实例,继续往下看就是c++相关的文件了,这里我贴一下IServiceManager 当中定义 serviceManager 的相关代码
这段代码在IServiceManager.cpp 文件中
using AidlServiceManager = android::os::IServiceManager;
上面所有的代码流程其实就是想说明一下,在activity 当中通过getSystemService 获取的 各类manager 都是 Binder 机制中的 Stub,我们可以通过Stub 进行跨进程通信 ,再来梳理一遍 IInterface 注册Stub 的整个过程
1.ZygoteInit fork app 进程 , 启动SystemServer.main()方法,在SystemServer main 方法中创建了一个 SystemServer,并执行SystemServer 的run 方法
2.SystemServer run方法中执行了3个比较重要的方法,其中startBootstrapServices 中 通过 SystemServiceManager 使用反射启动了 ActivityTaskManagerService.Lifecycle ,启动后将他放入到mservice 这个list 中,并执行service.onstart方法
3.ActivityTaskManagerService.Lifecycle 的onstart 方法中将 ActivityTaskManagerService.Lifecycle 初始化过程中创建的 ActivityTaskManagerService 放入publishBinderService 方法中, ActivityTaskManagerService 就是一个IInterface.Stub 的实例
4.SystemService 将 这个 Stub 放入到 ServiceManager 中
5.由ServiceManager 做了Native 的桥梁管理这些 IInterface.Stub ,
整个过程就是下面这种图这样的
image.png
本来这篇想写一下ActivityManagerService 的启动过程的,但是发现 ActivityManagerService 没有将这个IInterface.Stub 的实例放入到ServiceManager 当中,看来应该是没有对外调度的方法,或者不想让开发者参与进来,
根据ServiceManager 这个管理者我们可以理解为,ServiceManager 是通过binder 来进行跨进程的任务调度,他管理这所有进程的一些服务,
了解了Binder 的 基本通信逻辑,接下来我们继续分析一下bindService 这个过程中到底使用了几次跨进程通信
网友评论