Android源码分析:Activity启动流程

分析流程基于Android8.0源码

一般情况下我们通过Activity中的startActivity方法启动一个Activity。这个流程中涉及一下几个类:

android.app.Activity
android.app.Instrumentation

com.android.server.am.ActivityManagerService
com.android.server.am.ActivityStarter
com.android.server.am.ActivityStackSupervisor

android.app.ActivityThread
android.app.ActivityThread$ApplicationThread

通过下图了解一下各个类之间的调用关系


image

整个流程如上图所示,多数代码直接跟着进就可以看到,这里主要说一下两次IPC,通过每个类的包名可以间接反映出整个启动过程是一个C/S结构的跨进程操作。第一次跨进程是在Instumentation内部调用ActivityManagerService的startActivity方法时,代码如下:

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

看一下ActivityManager:

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

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;
            }
    };

这里通过ServiceManager.getService(Context.ACTIVITY_SERVICE)返回一个IActivityManager,就是一个ActivityManagerService,IActivityManager在/frameworks/base/core/java/android/app/目录下,是一个AIDL文件,里边声明了startActivity方法

interface IActivityManager {
    ...
    int startActivity(...);
    ...
}

ActivityManagerService继承了IActivityManager.Stub,实现StartActivity方法。这个方法的调用是在系统进程,之后的逻辑在系统进程里执行。


中间跟踪的代码如图,到ActivityStackSupervisor类中的realStartActivityLocked方法:

final boolean realStartActivityLocked(...) throws RemoteException {
    ...
    app.thread.scheduleLaunchActivity();
    ...
}

这里app.thread是一个ApplicationThread对象,ApplicationThread是ActivityThread的一个内部类,看一下ApplicationThread的相关代码:

private class ApplicationThread extends IApplicationThread.Stub {
    @Override
    public final void scheduleLaunchActivity(...) {
        ...
    }

ApplicationThread继承了IApplicationThread.Stub,这里也是跨进程的一步,这个时候就从系统进程回到了应用自己的进程,然后通过反射获取Activity实例,实例化Context,并调用获取Activity实例的attach方法,传入Context。最后调用到Activity的声明周期的方法。

总结:应用内启动Activity的逻辑主要经历了两次的跨进程过程,首先从应用自己进程跨进程到系统进程,处理Activity创建过程中的标志位判断,Activity所在的ActivityStack判断、初始化,等等,最后跨进程会应用自己进程实例化Activity,并调用Activity的生命周期方法。

你可能感兴趣的:(Android源码分析:Activity启动流程)