Android中关于Binder机制的一些感悟

前言

最近重温了Binder机制,在此把看到的一些心得,写一写。

正文

在这里需要先说明的一点是Client端和Server端以及后面提到的ServiceManager都处于用户空间、Binder驱动处于内核空间。

Binder是进程间通讯的一种方式。进程间的通讯方式有很多,比如Socket、管道。而Socket、管道这些需要数据的两次拷贝(Client把数据从自己的进程空间拷贝到内核空间,然后再从内核空间拷贝到Server端的进程空间,这样Server就能客户端传递的数据,这个过程经历过了两次数据拷贝)。而Binder方式只需要一次数据拷贝:只需要Client把数据拷贝到内核空间,然后将拷贝到内核空间的数据同时映射到Server进程虚拟地址空间和内核虚拟地址空间,这样经过一次数据拷贝,客户端和服务端就能进行通讯了。

注意:并不是所有的Binder服务都会注册到ServiceManager中的,像AMS、WMS、PMS这些系统的Binder服务是会注册到SM中并受SM管理的,而像bindService方式创建的Binder服务不会注册到ServiceManager中,这些注册到SM中的Binder服务称为实名Binder,不需要注册到ServiceManager中的Binder服务称之为匿名Binder,匿名Binder的传递和使用需要依赖于实名Binder。

借用网上某位大佬一张图,如图所示:

Android中关于Binder机制的一些感悟_第1张图片

Android启动的时候会启动SystemServer进程,SystemServer进程的入口是里面的main方法:

public static void main(String[] args) {
        new SystemServer().run();
}

这里又调用了SystemServer里面的run方法:

private void run() {
       ...

        // Start services.
        try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }
        ...
    }

我们看这里面的startBootstrapServices()方法:

private void startBootstrapServices() {
        ....
        // Activity manager runs the show.
        traceBeginAndSlog("StartActivityManager");
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
        traceEnd();

        ...

        traceBeginAndSlog("SetSystemProcess");
        mActivityManagerService.setSystemProcess();
        traceEnd();

        ...
    }

在这里,我们看到创建了ActivityManagerService对象,并通过下面的mActivityManagerService.setSystemProcess();启动了这个ActivityManagerService。

看下ActivityManagerService中的setSystemProcess()这个方法:

public void setSystemProcess() {
        ...

            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
        ...
}

在这里也就是执行了ServiceManager把创建的这个ActivityManagerService对象加入了ServiceManager中创建的映射表里。

Context.ACTIVITY_SERVICE其实就是“activity”字符串。到时候我们可以通过getService(Context.ACTIVITY_SERVICE),通过这个获取到存储在映射表里面的ActivityManagerService变量。例如:

ActivityManager activityManager = (android.app.ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

ActivityManager就是一个壳,它的存在避免了AMS直接暴露给应用程序,而是通过对外提供的ActivityManager来操作AMS,这样更安全,下面我们看一下ActivityManger里面的getService方法:

public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

看到这里面调用了IActivityManagerSingleton的get方法,看一下IActivityManagerSingleton:

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

首先看下Singleton类的定义:

package android.util;

/**
 * Singleton helper class for lazily initialization.
 *
 * Modeled after frameworks/base/include/utils/Singleton.h
 *
 * @hide
 */
public abstract class Singleton {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

其中get是final的方法,不可以覆盖,create是可以覆盖的。

主要看这里的两行代码:

final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;

 

这个地方是使用了AIDL的方式(Android7.0及之前,AMS通过代理模式来完成Binder通信,8.0之后,AMS通过AIDL完成Binder通信。),通过调用ServiceManager的getService方法查询出AMS的信息并转换为代理对象am。这个am对象是IActivityManager类型的,而IActivityManager是个aidl,根据aidl的规则和原理,可以知道远程服务的具体实现一定是IActivityManager.Stub的实现类,而AMS实现了IActivityManager.Stub,所以AMS是远程服务的具体实现。

你可能感兴趣的:(源码剖析,ActivityManager,AMS,Android,framework)