Android IPC --Binder 之源码篇(三)

上一篇文章我介绍了Binder的基本架构,实际上,我们在使用Binder进行跨进程通信的时候,最主要的就是三步: 服务注册、服务查找、服务调用,其中服务调用属于API调用,本文不做深入研究,因此,本文主要讲解Binder的服务注册、服务查找。在分析这部分的源码的时候,我们需要找一个切入点,这里我们就用AMS这个服务来分析Binder框架的切入点。

image.png

Binder 涉及到四层源码的 image.png

服务注册(AMS 的注册)

这里就涉及到Android系统启动流程。如下图,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AFql2El3-1654781103525)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/733b8602d5c14e339632833e348c73e1~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)]

  1. 启动电源以及系统启动: 当电源按下时引导芯片代码从预定义的地方(ROM)开始执行,加载引导程序BootLoader 到RAM , 然后执行。
  2. 引导程序: 引导程序BootLoader 是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。
  3. Linux 内核启动: 当内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置时,它首先在系统文件中寻找init.rc文件,并启动init 进程。
  4. init 进程启动: 初始化和启动属性服务,并且启动Zygote进程。
  5. Zygote 进程启动: 创建Java虚拟机并为Java 虚拟机注册JNI方法,创建服务器端Socket,启动SystemServer 进程。
  6. SystemServer进程启动:启动Binder 线程池,这样就可以和其他进程进行通信,创建SystemServiceManager(创建系统进程、启动和生命周期的管理),并且启动各种系统服务。
  7. Launcher 启动: 被SystemServer 进程启动的AMS会启动Launcher, Launcher 启动后会将已安装应用的快捷图标显示到界面上。

启动SystemServer 进程

本文要讲的AMS是在SystemServer进程中完成注册的,AMS就属于SystemServer 进程中的对象。我们看SystemServer 的源码,通过上图也可以看出SystemServer 是单独的一个进程,因此肯定会执行它的main 方法,Android 中通过java开启进程基本都是main(String[] args)方法。咱们进入该方法。

/**
 * The main entry point from zygote.
 */
public static void main(String[] args) {
    new SystemServer().run();
} 

通过注释The main entry point from zygote. 我们也看出这个是zygote 进程启动的。这个main 方法就一行代码,这行代码我们分两部分查看,先看

new SystemServer() 

这行代码是创建SystemServer 对象,我们看这个构造方法中做了什么

public SystemServer() {
    // Check for factory test mode.
    mFactoryTestMode = FactoryTest.getMode();
    // Remember if it's runtime restart(when sys.boot_completed is already set) or reboot
    mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));

    mRuntimeStartElapsedTime = SystemClock.elapsedRealtime();
    mRuntimeStartUptime = SystemClock.uptimeMillis();
} 

其实没做什么,这里不是我们要分析的关键,因此不做分析,我们接着看后面的一部分:run()

new SystemServer().run(); 
private void run() {
    try {
        ....
        Looper.prepareMainLooper();
        Looper.getMainLooper().setSlowLogThresholdMs(
                SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
        System.loadLibrary("android_servers");
        performPendingShutdown();
        createSystemContext();
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager)
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd();  // InitBeforeStartServices
    }

    // Start services.
    try {
        traceBeginAndSlog("StartServices");
        startBootstrapServices();  //这里执行了ActivityManagerService 的创建
        startCoreServices();
        startOtherServices();
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    }

    ...
    // Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
} 

咱们进入startBootstrapServices() 方法,就看ActivityManagerService 的创建注册流程,其他的咱们不关心

private void startBootstrapServices() {
  
    traceBeginAndSlog("StartActivityManager"); 
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService(); //1. 创建ActivityManagerService对象
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    traceEnd();

    ....
    // Set up the Application instance for the system process and get started.
    traceBeginAndSlog("SetSystemProcess");  
    mActivityManagerService.setSystemProcess();  //2. 将创建的ActivityManagerService对象注册到servicemanager 进程中,servicemanager 是内核进程。
    traceEnd();
} 

咱们先把下面的这部分分成两部分来看,其中注释2后面会讲解。

mSystemServiceManager.startService(
        ActivityManagerService.Lifecycle.class).getService(); 

先看前面一部分这个函数肯定返回了一个对象,然后才可以调用getService() 方法。

mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class) 

image.png 咱们看一下,这个mSystemServiceManager类中的startService 方法。咱们进入startService(Class) 方法。该方法的最后返回了通过反射创建的SystemService 对象。这里也即是ActivityManagerService 对象。

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 {
             //通过反射创建SystemService对象。
            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);
    }
} 

可能你会问上面的代码

mSystemServiceManager.startService(
        ActivityManagerService.Lifecycle.class).getService(); 

传入的是ActivityManagerService.Lifecycle.class,这个类是做什么的?我觉得有必要介绍一下这个内部类

public static final class Lifecycle extends SystemService {
    private final ActivityManagerService mService;

    public Lifecycle(Context context) {
        super(context);
        mService = new ActivityManagerService(context);
    }

    @Override
    public void onStart() {
        mService.start();
    }

    @Override
    public void onBootPhase(int phase) {
        mService.mBootPhase = phase;
        if (phase == PHASE_SYSTEM_SERVICES_READY) {
            mService.mBatteryStatsService.systemServicesReady();
            mService.mServices.systemServicesReady();
        }
    }

    @Override
    public void onCleanupUser(int userId) {
        mService.mBatteryStatsService.onCleanupUser(userId);
    }

    public ActivityManagerService getService() {
        return mService;
    }
} 

通过内部类持有外部类引用的这个特性,就可以做一些封装,实现部分的解耦,这边就在Lifecycle构造函数中创建了ActivityManagerService这个对象,然后提供了一个getService() 方法就将ActivityManagerService 返回给调用者了。


mActivityManagerService =

        ActivityManagerService.Lifecycle.class).getService(); 

这样,mActivityManagerService 变量就是ActivityManagerService 对象的一个引用。

接着咱们看上面遗留的 注释2部分的内容

private void startBootstrapServices() {
  
    traceBeginAndSlog("StartActivityManager"); 
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService(); //1. 创建ActivityManagerService对象
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    traceEnd();

    ....
    // Set up the Application instance for the system process and get started.
    traceBeginAndSlog("SetSystemProcess");  
    mActivityManagerService.setSystemProcess();  //2. 将创建的ActivityManagerService对象注册到servicemanager 进程中,servicemanager 是内核进程。
    traceEnd();
} 

咱们直接进入ActivityManager.setSystemProcess 方法。

public void setSystemProcess() {
    try {
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO); //这行代码是关键,这里调用了ServiceManager 的addService 方法。
        ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
        ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
                DUMP_FLAG_PRIORITY_HIGH);

      ....
    } catch (NameNotFoundException e) {
        throw new RuntimeException(
                "Unable to find android system package", e);
    }

 ....
} 

AMS 注册

咱们继续深入ServiceManager 类中的addService方法,从注释上咱们也可以看出一些信息,

/**
 * Place a new @a service called @a name into the service
 * manager.  将新创建的service放入到servicemanager中。
 * 
 * @param name the name of the new service
 * @param service the service object
 */
public static void addService(String name, IBinder service) {
    try {
        getIServiceManager().addService(name, service, false); //通过getIServiceManager() 获取到的对象,然后调用其上的addService 方法。
    } catch (RemoteException e) {
        Log.e(TAG, "error in addService", e);
    }
} 

同样,我们拆成两步来看,先看getIServiceManager() 做了什么。我们进入这个方法中,

private static IServiceManager sServiceManager;
private static IServiceManager getIServiceManager() {
    if (sServiceManager != null) {
        return sServiceManager;
    }

    //BinderInternal.getContextObject()  获取的的是BinderProxy
    // Find the service manager
    //sServiceManager == ServiceManagerProxy
    sServiceManager = ServiceManagerNative
            .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
    return sServiceManager;
} 

我们把sServiceManager = ServiceManagerNative .asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); 这部分拆成三部分来看,

  • BinderInternal.getContextObject()

  • Binder.allowBlocking(BinderInternal.getContextObject())

  • ServiceManagerNative .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()))

BinderInternal.getContextObject()

image.png

这部分返回的是BinderProxy 对象,我们先一步一步的深入到源码中,验证一下。从BinderInternal.java 类中可以看到getContextObject() 方法,从这个方法中可以看出是一个native方法。这个类的native实现类是android_util_Binder.cpp 现在咱们进入了Binder的JNI(Native)层了。

image.png

android_util_Binder.cpp 类中的方法

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);  
    return javaObjectForIBinder(env, b);
} 

上面方法中的两行代码,我们分别介绍下,先看

sp<IBinder> b = ProcessState::self()->getContextObject(NULL); 

通过ProcessState::self() 这是创建了一个ProcessState对象,sp 是软引用,

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState;
    return gProcess;
} 

然后这个对象调用对象方法:getContextObject(NULL)

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
} 

继续进入 getStrongProxyForHandle(0) 方法,该方法返回的对象就是BpBinder 对象,这个对象实现了IBinder 接口的。

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != NULL) {
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
               
                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }

            b = new BpBinder(handle);   //这个是重点,创建了BpBinder对象,这是发送方
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
         
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;
} 

咱们回到上面调用的地方,如下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P9ZGbQQl-1654781103534)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/62a308c59b9a4a3b8aaea9da703bce4b~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)]

这个方法返回的就是BpBinder 对象,接着回溯到上面,如下图:

image.png 现在我们进入javaObjectForIBinder() 方法,可以看到刚才创建的BpBinder 对象作为实参传入了该方法。咱们看源码的时候,需要关注的是一个方法的返回值是什么,然后这个返回值是怎么得到的,掌握主线路。

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    ...
    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); //这句是重点,这个创建的对象作为返回的实例。咱们要关注这个对象是什么。我们来分析下。
    if (object != NULL) {
        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
        // The proxy holds a reference to the native object. 这个注释也很关键,说的意思是BinderProxy会持有一个native 对象的引用。由于在c++ 中使用的是指针(地址)来和对象实现绑定的。因此是一个long类型的变量。
        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
        val->incStrong((void*)javaObjectForIBinder);

        jobject refObject = env->NewGlobalRef(
                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
        val->attachObject(&gBinderProxyOffsets, refObject,
                jnienv_to_javavm(env), proxy_cleanup);

        // Also remember the death recipients registered on this proxy
        sp<DeathRecipientList> drl = new DeathRecipientList;
        drl->incStrong((void*)javaObjectForIBinder);
        env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));

        // Note that a new object reference has been created.
        android_atomic_inc(&gNumProxyRefs);
        incRefsCreated(env);
    }

    return object;
} 

接下来,我们分析下下面这行代码创建对象是什么。这个object 到底是什么对象的指针引用

object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);     //创建的就是android.os.BinderProxy 对象 

这里通过反射创建的对象,我们要关注的是NewObject()中的第一个参数,对应的是那个类的class。我们就要看这个gBinderProxyOffsets.mClass 在哪赋值的 ,我们来找一找

image.png

由上图我们可以看到,这个gBinderProxyOffsets.mClass就是指的是android.os.BinderProxy 类。由此可知上面的object == android.os.BinderProxy,咱们一步一步往回走,就可得知最上层调用的地方了。

image.png

//BinderInternal.getContextObject()  获取的的是BinderProxy
sServiceManager = ServiceManagerNative
        .asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); 

这个过程我来画一张图,比较清晰一步一步的流程, 最终,我们BinderInternal.getContextObject() 就是一个BinderProxy对象

image.png

image.png

Binder.allowBlocking(BinderInternal.getContextObject())
public static IBinder allowBlocking(IBinder binder) {
    try {
        if (binder instanceof BinderProxy) {
            ((BinderProxy) binder).mWarnOnBlocking = false;
        } else if (binder != null && binder.getInterfaceDescriptor() != null
                && binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
            Log.w(TAG, "Unable to allow blocking on interface " + binder);
        }
    } catch (RemoteException ignored) {
    }
    return binder;
} 

这个方法没什么介绍的,看源码即可,实际上返回的还是BinderProxy 对象。

ServiceManagerNative.asInterface()

image.png 进入到了ServiceManagerNative 类中的方法,通过注释我们也能看到,最终我们要进入ServiceManagerProxy 类中,我们进入看一下:我都加了注释。

class ServiceManagerProxy implements IServiceManager {
    private IBinder mRemote;
    //这个mRemote 就是BinderProxy
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
    }

    public IBinder asBinder() {
        return mRemote;
    }

    public void addService(String name, IBinder service, boolean allowIsolated)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); // 这个Binder 通信实际上都是通过BinderProxy 这个代理类来实现通信的。
        reply.recycle();
        data.recycle();
    }

} 

通过这个分析我们就看到这个,最终sServiceManager=ServiceManagerProxy 对象。而该对象中进行跨进程通信又是由BinderProxy 这个对象来完成的。

//BinderInternal.getContextObject()  获取的的是BinderProxy
sServiceManager = ServiceManagerNative
        .asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); 

咱们回到上面ServiceManager 类中的addService方法,

/**
 * Place a new @a service called @a name into the service
 * manager.  将新创建的service放入到servicemanager中。
 * 
 * @param name the name of the new service
 * @param service the service object
 */
public static void addService(String name, IBinder service) {
    try {
        getIServiceManager().addService(name, service, false); //通过getIServiceManager() 获取到的对象,然后调用其上的addService 方法。
    } catch (RemoteException e) {
        Log.e(TAG, "error in addService", e);
    }
} 

我们知道这个getIServiceManager() 就是ServiceManagerProxy 对象,调用的addservice 方法就是该对象中的方法,

public void addService(String name, IBinder service, boolean allowIsolated)
        throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IServiceManager.descriptor);
    data.writeString(name);
    data.writeStrongBinder(service);
    data.writeInt(allowIsolated ? 1 : 0);
    mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
    reply.recycle();
    data.recycle();
} 

现在咱们就走到了mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); 方法中,这个mRemote== BinderProxy,继续深入敌后,

public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
    Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
    ...
    try {
        return transactNative(code, data, reply, flags);  //这个是关键点。我们只找关键点
    } finally {
        if (transactListener != null) {
            transactListener.onTransactEnded(session);
        }

        if (tracingEnabled) {
            Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
        }
    }
} 

我们只看 transactNative(code, data, reply, flags); 这行代码,又是native 方法。

image.png

我们要看下这个在native层对应的是哪个类?

image.png

在android_util_Binder 类中android_os_BinderProxy_transact 方法, 我们走进去看一下:

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
    if (dataObj == NULL) {
        jniThrowNullPointerException(env, NULL);
        return JNI_FALSE;
    }

    Parcel* data = parcelForJavaObject(env, dataObj);   //这个是发送的序列化数据
    if (data == NULL) {
        return JNI_FALSE;
    }
    Parcel* reply = parcelForJavaObject(env, replyObj); //这个是接受的序列化数据
    if (reply == NULL && replyObj != NULL) {
        return JNI_FALSE;
    }

    IBinder* target = (IBinder*)
        env->GetLongField(obj, gBinderProxyOffsets.mObject);  //这个是关键点,需要分析,我们要看一下这个target 指针所指的对象是啥。
    if (target == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
        return JNI_FALSE;
    }
  ...
#endif
    //printf("Transact from Java code to %p sending: ", target); data->print();
    status_t err = target->transact(code, *data, reply, flags);  //这个调用就是BpBinder 的方法调用了。
    //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
#if ENABLE_BINDER_SAMPLE
    if (time_binder_calls) {
        conditionally_log_binder_call(start_millis, target, code);
    }

    ...
    return JNI_FALSE;
} 

这个方法里面我们重点就是关注IBinder* target = (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject); 这个target 指针所指向的对象是哪个对象。这里咱们就要查gBinderProxyOffsets.mObject 这个所指的是什么了?我们看一下这个是在哪里赋值的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fK1UkiQU-1654781103546)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/deaa0edb39384b49a489dcedbfb51789~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)] 从这里看出是BinderProxy 中一个mObject 的一个字段所指的native 方法中创建的一个对象的地址。 ** 接着咱们看这个地址是在哪里赋值的。咱们在前面javaObjectForIBinder** 方法中说过,一个关键点。

image.png 前面分析过这个val 变量就是BpBinder. 由此我们可以得出结论: gBinderProxyOffsets.mObject = BpBinder. 咱们回到 上面的这个地方,就得知target=BpBinder

image.png

接着我们就可以看上面的源码,得出下面的结论:

target->transact(code, *data, reply, flags) 就是BpBinder 的调用, image.png 现在咱们就进入了BpBinder 类中了。从下面 的图中我们也可以看出确实走到了BpBinder::transact() 方法了。

image.png

status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);    //这个方法就是要调用内核层的代码了。我不打算分析了。我也看不懂哈哈哈。
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
} 

从这里,在加上 上图,就可以得知,我们注册的服务一步步的添加进到内核中了。这就是服务的注册

未命名文件 (1).jpg

服务发现(AMS)

这里我们还是以AMS 为例,我们调用startActivity 方法。会走到Activity 的startActivity(Intent intent)方法

image.png 接着进入,会走到下面的这个方法中 startActivity(Intent intent, @Nullable Bundle options)

image.png

由于options = null , 就会走红框标注的部分startActivityForResult(intent, -1, options); 接着走进去,

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null);
} 

继续进入

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options); //这个是重点,我们要进入看一看。
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
       ...
    } else {
      ...
    }
} 

从上面的源码中,我们可以看到通过 Instrumentation 这个类中的mInstrumentation.execStartActivity 方法。

image.png 我们重点看标红的那部分代码,

int result = ActivityManager.getService()
    .startActivity(whoThread, who.getBasePackageName(), intent,
            intent.resolveTypeIfNeeded(who.getContentResolver()),
            token, target != null ? target.mEmbeddedID : null,
            requestCode, 0, null, options); 

这个ActivityManager.getService() 就是发现服务 我们进入看一下,它是怎么一步一步查找服务的。

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

    protected abstract T create();

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

先要看一下上面这个抽象类,封装了单例的实现,这个Signleton 是Android 封装的一个单例的抽象类。我们只需要实现create() 方法,然后通过get() 方法就可以得到我们再create() 中创建的对象。

/**
 * @hide
 */
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;
            }
        }; 

从上面的代码可以看出,IActivityManagerSingleton.get() 方法获取到的就是我们要得到的对象,这个IActivityManagerSingleton 是一个单例。这个Signleton 是Android 封装的一个单例的抽象类。我们只需要实现create() 方法,然后通过get() 方法就可以得到我们再create() 中创建的对象,由此,我们可以解释,IActivityManagerSingleton.get()=am

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lFehsyqt-1654781103553)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8db05c38b70d458793ce23b928024aa2~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)]

现在我们把ServiceManager.getService(Context.ACTIVITY_SERVICE); 抽出来,重点分析这行代码,就是发现服务的关键。 直接进入ServiceManager.getService(String name)方法

public static IBinder getService(String name) {
    try {
        IBinder service = sCache.get(name);
        if (service != null) {
            return service;
        } else {
            return Binder.allowBlocking(rawGetService(name));  //直接看这行代码。
        }
    } catch (RemoteException e) {
        Log.e(TAG, "error in getService", e);
    }
    return null;
} 

咱们直接看Binder.allowBlocking(rawGetService(name)) 这行代码的rawGetService(name) 部分。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4ZcyDlYL-1654781103554)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6f70ea013ffe4ddf85227420a299914c~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)]

看到1 这行代码, final IBinder binder = getIServiceManager().getService(name); 分为两部分

  • getIServiceManager()
  • getIServiceManager().getService(name)

getServiceManager() 在服务注册的时候我们分析过了,这里我们不再讨论。只需要记住这个getIServiceManager()=ServiceManagerProxy 这个对象,其中所有的方法调用最终都是调用其内部变量mRemote=BinderProxy这个对象的方法。

public IBinder getService(String name) throws RemoteException {
   Parcel data = Parcel.obtain();
   Parcel reply = Parcel.obtain();
   data.writeInterfaceToken(IServiceManager.descriptor);
   data.writeString(name);
   mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
   IBinder binder = reply.readStrongBinder();
   reply.recycle();
   data.recycle();
   return binder;
} 

业务方法code和参数打包,调用BinderProxy的transact方法进行通信,sm进程读取到查询请求时,根据服务字符串对应服务Binder,(sm进程的查询流程,以及为什么没有业务实现类,等写sm源码相关时再分析)。然后,通过Parcel的readStrongBinder方法,读取IBinder,它就是我们查找对应服务的BinderProxy 到这里,服务查找基本就结束了。

未命名文件 (2).jpg

总结

Java层Binder服务查找、注册的流程, 在Java层,请求进程依赖BinderProxy和业务XxxProxy,服务进程依赖Binder和业务Xxx服务。 系统服务查找和注册都需要与sm进程通信。一般情况下,注册者是服务提供的system_server进程,查找者是App进程。 sm进程是Binder服务管理者, Binder服务需要向它注册才可以被使用。
ServiceManager类,框架层提供的一个服务操作类,可以通过该类提供的addService和getService方法,与sm进程通信。该类内部提供了和sm进程通信BinderProxy代理和业务代理。
与sm进程通信的BinderProxy,**由BinderInternal类的getContextObject方法获取。

image.png

文末

要想成为架构师,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

一、架构师筑基必备技能

1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……

在这里插入图片描述

二、Android百大框架源码解析

1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程

在这里插入图片描述

三、Android性能优化实战解析

  • 腾讯Bugly:对字符串匹配算法的一点理解
  • 爱奇艺:安卓APP崩溃捕获方案——xCrash
  • 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
  • 百度APP技术:Android H5首屏优化实践
  • 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
  • 携程:从智行 Android 项目看组件化架构实践
  • 网易新闻构建优化:如何让你的构建速度“势如闪电”?

在这里插入图片描述

四、高级kotlin强化实战

1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》

  • 从一个膜拜大神的 Demo 开始

  • Kotlin 写 Gradle 脚本是一种什么体验?

  • Kotlin 编程的三重境界

  • Kotlin 高阶函数

  • Kotlin 泛型

  • Kotlin 扩展

  • Kotlin 委托

  • 协程“不为人知”的调试技巧

  • 图解协程:suspend

在这里插入图片描述

五、Android高级UI开源框架进阶解密

1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南
在这里插入图片描述

六、NDK模块开发

1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习

在这里插入图片描述

七、Flutter技术进阶

1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)

在这里插入图片描述

八、微信小程序开发

1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……

在这里插入图片描述

全套视频资料:

一、面试合集
在这里插入图片描述
二、源码解析合集

在这里插入图片描述
三、开源框架合集

在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取【保证100%免费】↓↓↓

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值