一、梳理源码流程干什么

Activity是四大组件中最重要的组件之一,下面来分析Activity的启动过程,了解Activity的启动过程能帮助我们更好的对组件Activity的理解,也能帮助我们更好的把控Activity生命周期的变化过程。

当然Activity作为四大组件之首,10.0版本的Activity的代码函数在8000行,关联的一些类Instrumentation、ActivityTaskManager、ActivityStarter等等,怎么也是几万行的代码,一次完全分析起来会很困难,这里面主要通过启动的核心流程源码分析,帮我们理清楚Activity的启动流程,内部其实有很多细节,这些细节和我们的日常开发也都非常相关,关于这部分细节性的代码,由于篇幅问题,本文并不会全部体现。

先上Activity启动流程梳理图:

上图非完整的启动流程,在后续源码分析中,还有第二条分支,就是当application未创建的情况下,会去创建进程,fork应用进程等,后文的源码分析中会简单提到,详细流程也适合做专题分析。

通过这样的一个梳理图,主要是清晰系统进程和应用进程中的代码调用流程,建议先初步看一下梳理图,在看后面的源码分析过程中不断的回到图中来,加深自己的理解和印象,在文章末尾,源码分析之后,也会对梳理图中的核心类进行说明。

二、源码流程分析

下面主要从源码角度来进行分析,分析的入口就是startActivity(),分析源码中的Activity.java中的startActivity()方法

2.1 应用进程StartActivity

public void startActivity(Intent intent, @Nullable Bundle options) {
        ......
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

从上述代码来看startActivity的方法体来看,最终都会调用startActivityForResult()方法,接下来看startActivityForResult方法源码:

 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {//标注1
            options = transferSpringboardActivityOptions(options);
            //标注2
            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());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {//标注3
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

在startActivityForResult方法体中,先看到了标注1的位置是一个条件判断mParent==null。mParent代表的是ActivityGroup,Api13已经被废弃,这里面其实我们标注3的内容就不用太多去关注了,当然从方法名上mParent.startActivityFromChild也能看出来,的确是子Activity来启动Activity。我们把关注点仍然回到标注2的位置

mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);

mInstumentation好像很面熟,当然这个类比我们想象的要强大的多,Instrumentation为仪表盘,管理着Activity和Application的生命周期,一个进程对应了一个Instrumentation。

在后续的分析过程中,我们会看到Instrumentation在整个Activity启动过程中的强大作用,接下来我们继续分析execStartActivity的核心流程

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        省去非核心流程代码...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            //这块的代码和8.0的是有区别,这块也是我们启动流程里面的核心代码
            //8.0里面的源码:ActivityManagerNative.getDefault()
            int result = ActivityTaskManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

上述标注1的位置,可以看到启动activity的真正实现交给了ActivityTaskManager.getService()的startActivity的方法了。

 public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
    }
 private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() {
                @Override
                protected IActivityTaskManager create() {
                  //获得Binder对象实例
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                    return IActivityTaskManager.Stub.asInterface(b);
                }
            };

从这里可以推测,此处把application启动的过程要转交给通过ActivityTaskManager获得IActivityTaskManagerSingleton的单例对象去处理,上述备注部分,可以看出返回的是一个Aidl的接口实例。

我们也查看IActivityTaskManager的实现类,通过源码我们找到了ActivityTaskManagerService继承了IActivityTaskManager。

public class ActivityTaskManagerService extends IActivityTaskManager.Stub{...省去...}

从这里,也可以印证:同一个应用A activity启动一个B activity 本质上也是一个跨进程调用的过程。

为什么这里面需要用AMS的Binder对象呢?

看到Binder,有些android知识储备的应该能想到这是跨进程通信,那么到底哪两个进程进行了跨进程的通信?这里面需要了解到ActivityManagerService实际上是在android系统启动的时候,这个服务就被开启了,这个服务被运行在系统进程中,即ActivityMangerService是运行在android system进程中的,并且系统一启动,这个service就会被启动。这里面显然是我们自己的app进程和system进程之间进行了ipc调用。

2.2进入到ATMS进程startActivity

ATMS,即ActivityTaskServiceManager,运行在系统服务进程中,继续看ActivityTaskManagerService中的源码:

@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}

实际会调用startActivityAsUser()。startActvityAsUser()的实现:

int startActivityAsUser(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
        boolean validateIncomingUser) {
    ...
    // TODO: Switch to user app stacks here.
    return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setMayWait(userId)
            .execute();//实际调用的是ActivityStarter的excute的方法

}

execute的方法实际ActivityStarter类在执行,之后再调用到startActivityUnchecked(),再调用到RootActivityContainer类中resumeFocusedStacksTopActivities(),最终会调用到ActivityStack的resumeTopActivityUncheckdeLocked(),RootActivityContainer类中的代码调用如下

if (!resumedOnDisplay) {
    // 查找符合条件的任务栈
    final ActivityStack focusedStack = display.getFocusedStack();
    if (focusedStack != null) {
        focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
}

ActivityStack中的resumeTopActivityUncheckedLocked()的源码:

/**
 * 确定栈顶Activity是否是resumed
 */
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    if (mInResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }
    boolean result = false;
    try {
        mInResumeTopActivity = true;
        //核心代码:
        result = resumeTopActivityInnerLocked(prev, options);
        // 栈顶有resuming的activity,有必要进行pause 
        final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
        if (next == null || !next.canTurnScreenOn()) {
            checkReadyForSleep();
        }
    } finally {
        mInResumeTopActivity = false;
    }

    return result;
}

可以看到在ActivityStack的resumeTopActivityUncheckeLocked方法中个,继续调用了resumeTopActivityInnerLocked();在此方法中,针对于activity启动流程环节,要使得栈中的resume的Activity进行暂停:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
  .....
	if (mResumedActivity != null) {
    if (DEBUG_STATES) Slog.d(TAG_STATES,
            "resumeTopActivityLocked: Pausing " + mResumedActivity);
    pausing |= startPausingLocked(userLeaving, false, next, false);
	}
  ....
}

关于pause栈顶Activity的内部流程,这块不做详细分析(在源码分析Activity生命周期专题中再做分析)。我们要继续回调启动Activity的核心流程里面来,在上述方法中,通过一系列的处理,最终会调用到启动Activity的方法里面来:

if (next.attachedToProcess()) {
		...
		 mService.getLifecycleManager().scheduleTransaction(transaction);
		....
}else{
     // Whoops, need to restart this activity!
     if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
      } else {
            if (SHOW_APP_STARTING_PREVIEW) {
              next.showStartingWindow(null /* prev */, false /* newTask */,
                            false /* taskSwich */);
             }
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
      }
      if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
}

如上代码片段,一堆处理后,同样在resumeTopActivityInnerLocked方法中,会调用mStackSupervisor.startSpecificActivityLocked()。此方法的源码:

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // 判断当前要启动的Activity的application是否已经存在
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        // 如果已经存在,主线程也正常
        if (wpc != null && wpc.hasThread()) {
            try {
                //调用真实启动Activity的方法
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                //return 后续的逻辑都不会走
                return;
            } catch (RemoteException e) {
                ... //出现异常
            }

            //出现异常重启application(现在好多手机,应用奔溃后,都能自启,待验证)
            knownToBeDead = true;
        }
        if (getKeyguardController().isKeyguardLocked()) {
            r.notifyUnknownVisibilityLaunched();
        }

        try {
            ...
            // 走到这里,说明进程未创建,意义启动进程的消息
            final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, 	mService.mAmInternal,r.processName,r.info.applicationInfo, knownToBeDead, "activity",r.intent.getComponent());
            //通过ActivityTaskManagerService中的Handler发送消息,创建一个新的进程
            mService.mH.sendMessage(msg);
        } finally {
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

在这个流程中,实际存在两个分支逻辑,一条分支是在当前的application中去启动Activity,另一个分支先创建当前要启动的Activity所需要的进程。先看mStackSupervisor.realStartActivityLocked():

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
  ...
    try {
                if (!proc.hasThread()) {
                    //远程调用异常
                    throw new RemoteException();
                }
      					......
      					// 创建Activity启动事务.proc.getThread()是applicationThread
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);

                final DisplayContent dc = r.getDisplay().mDisplayContent;
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.icicle, r.persistentState, results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                                r.assistToken));

                // 设置预期的最终状态
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // 启动事务
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    } catch (RemoteException e) {
           //远程调用异常     
    }

ClientTransaction是啥呢,简单看一下这个例的文档注释:

/**
 * 持有一系列消息,用于和client交互(app进程)
 * This includes a list of callbacks and a final lifecycle state.
 */
public class ClientTransaction implements Parcelable, ObjectPoolItem {}

回到realStartActivityLocked()方法的源码中来,也特地贴出了catch的异常,很显然这部分代码的执行,仍然是在系统进程中执行。上述代码中添加了核心代码的中文注释,可以看到这段代码中,主要是创建事务,同时传入ApplicationThread,而ApplicationThread继承于Binder,传入的目的就是后面要和目标App进程进行通信。mService.getLifecycleManager().scheduleTransaction(clientTransaction);这句代码,是计划启动事务。继续看这部分的源码:

/**
 * 计划一个事务,包含多个callbacks和lifecycle request
 */
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    //核心代码
    transaction.schedule();
    if (!(client instanceof Binder)) {
        transaction.recycle();
    }
}

接下来就是ClientTransaction:

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

实际调用额是mClient.scheduleTransaction(),mClient这个全局变量是什么呢?

在上述代码片段中有创建ClientTransaction的方法调用:

final ClientTransaction clientTransaction = ClientTransaction.obtain(
        proc.getThread(), r.appToken);

追一下这个obtain方法的源码:

/** Obtain an instance initialized with provided params. */
public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
    ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
    if (instance == null) {
        instance = new ClientTransaction();
    }
    //ClientTransaction中的全局对象mClient在这里赋值为ApplicationThread
    instance.mClient = client;
    instance.mActivityToken = activityToken;

    return instance;
}

mClient.scheduleTransaction(this);从这里开始,是从ATMS进程跨进程调用ApplicationThread的scheduleTransaction()方法,到App进程中代码继续分析。

2.2 进入App进程创建Activity

private class ApplicationThread extends IApplicationThread.Stub {
        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }
}

上图中,ApplicationThread是ActivityThread的私有内部类,继承IApplicationThread.Stub,它的本质也是Binder,对照源码分析的开始位置的IActivityManager,可以看出:

IApplicationThread是提供给ATMS进程访问App进程的入口;

IActivityManager是提供给应用进程访问ATMS进程的入口;此两者都是跨进程通信过程。

回到上述的代码中,会调用到ActivityThread.this.scheduleTransanction(),跟踪方法后,实际上走到的是ActivityThread的父类中的scheduleTransaction():

/** 准备和计划事务的执行 */
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

最终会调用到ActivityThread中的mH.sendMessage(msg); H继承Handler,是ActivityThread的中内部类。

class H extends Handler {
  public static final int EXECUTE_TRANSACTION = 159;
  public void handleMessage(Message msg) {
    ...
    case EXECUTE_TRANSACTION:
         final ClientTransaction transaction = (ClientTransaction) msg.obj;
         //关键执行代码
         mTransactionExecutor.execute(transaction);
         ....
         break;
    .....
  }
}

TransanctionExecutor的源码:

/**
 * 管理事务按照顺序执行
 * @hide
 */
public class TransactionExecutor {
      //解析transaction,首先所有的callbacks会顺序执行,之后会处理生命周期状态。
			public void execute(ClientTransaction transaction) {
            ...
            executeCallbacks(transaction);
            //本流程不做详细分析,梳理图中会提现,会构建PauseActivityItem
            executeLifecycleState(transaction);
            ...
      }
}

接下来我们继续看excuteCallbacks方法的源码:

 public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();   
        .....
 
    final int size = callbacks.size();
    for (int i = 0; i < size; ++i) {
        //遍历callbacks并执行
        final ClientTransactionItem item = callbacks.get(i);
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
        final int postExecutionState = item.getPostExecutionState();
        final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                item.getPostExecutionState());
        if (closestPreExecutionState != UNDEFINED) {
            cycleToPath(r, closestPreExecutionState, transaction);
        }
        //item的类型其实就是LaunchActivityItem
        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
        
        .....
    }
}

遍历callbacks并执行,callbacks是什么时候添加的,在前面realStartActivityLocked方法中,创建启动Activity任务的时候添加:

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
                ....
                //创建Activity启动事务.proc.getThread()是applicationThread
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);
                final DisplayContent dc = r.getDisplay().mDisplayContent;
                //把LaunchActivityItem加入事务中,后面会调用到该类的handleLaunchActivity()方法
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.icicle, r.persistentState, results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                                r.assistToken));
                ....
}

item.execute,实际上就是LaunchActivity类的excute方法,源代码如下:

/**
 * 发起一个activity启动的请求
 */
public class LaunchActivityItem extends ClientTransactionItem {
@Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        ....
        //核心代码就这一句
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        ....
    }
}

这里面client是啥呢,其实就是ClientTransactionHandler,找到handleLaunchActivity方法,发现是个抽象方法:

/** Perform activity launch. */
public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent);

通过追代码,实际调用的地方在ActivityThread中:

@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    ...
    //windowManage初始化,一个Activity对一个window窗口
    WindowManagerGlobal.initialize();
    //核心是这句代码
    final Activity a = performLaunchActivity(r, customIntent);
    ...
}

接下来就是Activity启动的核心实现,为什么这么说呢,源码里面的文档注释就是这么说的,看源码:

/**  Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
      ...
        //真正创建Activity的地方
        //为Activity创建context上下文
        ContextImpl appContext = createBaseContextForActivity(r);
        //声明Activity
        Activity activity = null;
        try {
            //获取classLoader
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //通过instrumentation仪表盘,创建Activity(反射)
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            //严格模式相关代码,忽略
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            ....
        }
  			try {
            //获取application,虽然是make方法,但是内部实现application!=null会直接返回
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            if (activity != null) {
 								....
                //声明一个window
                Window window = null;
                ...
                appContext.setOuterContext(activity);
                ...
                //将activity和window绑定
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback,
                        r.assistToken);
								//处理intent
                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                checkAndBlockForNetworkAccess();
                activity.mStartedActivity = false;
              	//设置主题
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
              	//回调Activity的生命周期方法onCreate
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
               ...
                r.activity = activity;
            }
            r.setState(ON_CREATE);
        } catch (SuperNotCalledException e) {
           ...
        } 
   return activity;
}

核心的Activity的启动代码,看起来还是比较容易的,上文的代码中的核心代码的注释都已经说明,主要就做了如下几件事情:

1、使用反射创建目标Activity对象

2、创建PhoneWindow对象

3、通过调用attch方法将Activity和PhoneWindow绑定

4、回调Activity的onCreate方法。

继续看内部方法的实现细节源码:

public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    //预处理
    prePerformCreate(activity);
    //执行Activity的performCreate()
    activity.performCreate(icicle, persistentState);
    postPerformCreate(activity);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        //真正回调Activity生命周期的方法的位置
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ....
    }

protected void onCreate(@Nullable Bundle savedInstanceState) {
        ....
    }

至此,Activity被启动,并开始了生命周期方法的正常回调。

.3创建新的目标进程

前面在分析startSpecificActivityLocked()方法中,提到当前待启动的activity所需application进程是否存在,走了如下代码中所示的两个分支逻辑。前面已经分析过了其中的一种情况存在,如果不存在Activity整个的启动过程又是怎样子的呢?

这种情况下的启动和我们通常所讲android应用启动的过程是一致的。

继续分析:

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    // 判断当前要启动的Activity的application是否已经存在
    final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);    
     boolean knownToBeDead = false;
    // 如果已经存在,主线程也正常
    if (wpc != null && wpc.hasThread()) {
        try {
            //调用真实启动Activity的方法
            realStartActivityLocked(r, wpc, andResume, checkConfig);
            //return 第一条分支逻辑
            return;
        } 
    }
    try {
        ...
        // 第二条分支逻辑
        final Message msg = PooledLambda.obtainMessage(
                ActivityManagerInternal::startProcess, 	mService.mAmInternal,r.processName,r.info.applicationInfo, knownToBeDead, "activity",r.intent.getComponent());
        //通过ActivityTaskManagerService中的Handler发送消息,创建一个新的进程
        mService.mH.sendMessage(msg);
    } finally {
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
}

这个方法是在ActivityStackSupervisor类中,在obtainMessage方法中ActivityManagerInternal::startProcess这个参数,是java8的语法,实则是调用了ActivityManagerInternal中的startProcess方法,ActivityManagerInternal是一个抽象类,它的实现类在AMS中,即ActivityManagerService中,即LocalService。

public void onActivityManagerInternalAdded() {
    synchronized (mGlobalLock) {
        //实现类是localService
        mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
        mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
    }
}

mService.mH.sendMessage(msg);:mService为ATMS对象,mH前面也提到过是定义在ATMS中的一个Handler。

接着我们就看一下ATM中的startProcess方法的源码实现:

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        @Override
        public void startProcess(String processName, ApplicationInfo info,
                boolean knownToBeDead, String hostingType, ComponentName hostingName) {
            try {
                ....
                //下面这段就是核心代码
                synchronized (ActivityManagerService.this) {
                    startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                            new HostingRecord(hostingType, hostingName),
                            false /* allowWhileBooting */, false /* isolated */,
                            true /* keepIfLarge */);
                }
            } 
          ...
        }
}

这里呢,我们就一致追踪startProcessLocked方法,经过多个调用后,最后会走到ProcessList类中startProcess方法:

private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    try {
     
        final Process.ProcessStartResult startResult;
        if (hostingRecord.usesWebviewZygote()) {
            ....
        } else if (hostingRecord.usesAppZygote()) {
           ....
        } else {
            //最终会调用到这个地方
            startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith, app.info.packageName,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        }
        checkSlow(startTime, "startProcess: returned from zygote!");
        return startResult;
    } ...
}

上面,不同的zygote进程start的判断,此流程中会走到最后的else,继续看Process.start方法源码:

/**
 * 通过zygote进程创建一个新的进程。
 * 新的进程被创建,进程class中的static main()在这里被执行
 */
public static ProcessStartResult start(@NonNull final String processClass,
                                       @Nullable final String niceName,
                                       int uid, int gid, @Nullable int[] gids,
                                       int runtimeFlags,
                                       int mountExternal,
                                       int targetSdkVersion,
                                       @Nullable String seInfo,
                                       @NonNull String abi,
                                       @Nullable String instructionSet,
                                       @Nullable String appDataDir,
                                       @Nullable String invokeWith,
                                       @Nullable String packageName,
                                       @Nullable String[] zygoteArgs) {
    return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, packageName,
                /*useUsapPool=*/ true, zygoteArgs);
}

这里return中调用的ZYGOTE_PROCESS.start,ZYGOTE_PROCESS就是系统中的Zygote进程,经常被称为受精卵,Android中所有的App进程都是由Zygote进程fork生成的,另一个角度,既然是受精卵,那么Zygote进程可以理解成是android中所有java进程的父进程。

到这来就开始了目标App进程的创建了,目标进程创建成功,会立即启动ActivityThread线程,并进入到main方法。接下来就进入到ActivityThread的main入口的源码分析。

(这里面没有再深度分析,Zygote进程是如何fork子进程的流程细节,本节的重点是关注Activity启动的大流程上)

.4目标进程main函数(作为程序入口)的源码分析

ActivityThread的main函数源码:

public static void main(String[] args) {
    ...
    //准备主循环器
    Looper.prepareMainLooper();
    ...
    //创建ActivityThread并进行attach
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
    //这段代码将sMainThreadHandler引用指mH,但是并没有查找到sMainThreadHander太多使用的地方
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    ...
    //循环器循环起来
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

小提示:上面的sMainThreadHandler、mH实际都指向new H(),只是sMainThreadHandler是静态的,可以直接提供给外部使用,在SharePreferencesImpl的源码中,能找到这段代码的使用:

ActivityThread.sMainThreadHandler.post(() -> notifyListeners(mcr));

上面的代码中已经添加了注释,main函数的代码流程相对清晰明了,主要干了下面几个步骤:

1、准备主循环器

/**
 * 初始化当前线程作为一个looper, 并且使它成为application的主looper. 
 * 这个方法是被系统调用的,前面我们分析过,main方法是经过AMS一步步调用过来的
 */
public static void prepareMainLooper() {
    prepare(false);
    synchronized (Looper.class) {
        if (sMainLooper != null) {
            throw new IllegalStateException("The main Looper has already been prepared.");
        }
        sMainLooper = myLooper();
    }
}

prepare():

public static void prepare() {
    prepare(true);
}
private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
      //每个线程只能创建一个looper
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}

looper对象的创建,同时会创建MessageQueue。

2、创建ActivityThread并进行attach

private void attach(boolean system, long startSeq) {
  ...
   final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
  ...
}

非系统进程走到上述逻辑中,IActivityManager.getService获得是AMS对象,这里面是一次跨进程调用,将ActivityThread和应用绑定起来(后文会继续分析)。

3、循环器循环起来,Looper.loop的源码如下:

public static void loop() {
   for (;;) {
     ....省去了大量代码....
      Message msg = queue.next(); // might block
      msg.target.dispatchMessage(msg);
     ....省去了大量代码....
   }
}

loop()方法,核心就是一个无限循环,然后从messageQueue中获取消息,并消息分发出去。篇幅太长,关于Handler、Looper的在这里也不做详细分析。

.5 在AMS进程中执行Application的初始化和启动Activity

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
   @Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            //关键代码
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }
}

接着会调用

private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
        //绑定application
        thread.bindApplication(...);
        //绑定application后激活app,客户端可以运行请求,比如starting activity
        app.makeActive(thread, mProcessStats);
        //去启动activity,从句代码中,并不能看出来,后文会继续分析
        didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
}

当前代码执行在AMS中,AMS进程通过thread.bindApplication再一次跨进程调用到app进程。

2.6 app进程中初始化Application

详细看一下bindApplication的实现源码如下:

public final void bindApplication(...太长的参数....) {
        //核心就一句代码,发送消息
         sendMessage(H.BIND_APPLICATION, data);
        }

消息的处理:

class H extends Handler {
    public static final int BIND_APPLICATION        = 110;
   	public void handleMessage(Message msg) {
            switch (msg.what) {
                case BIND_APPLICATION:
                    //关键代码
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    break;
                ....
            }
    }
}

继续调用:handleBindApplication(data):

private void handleBindApplication(AppBindData data) {
      ....
      final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                    appContext.getClassLoader(), false, true, false);
      ....
      //使用pi(laodAPK 创建application的上下文)
      final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
                    appContext.getOpPackageName());
      //创建application,这个方法在之前的第一个分支逻辑中,也是存在的,第一个分支逻辑中application
      //为非空,第二个分支就是当前分析的流程,makeApplication内部调用的时候,通过反射去创建了   application
      app = data.info.makeApplication(data.restrictedBackupMode, null);
      ....
      try {
           final ClassLoader cl = instrContext.getClassLoader();
           //创建仪表盘对象
           mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
          } catch (Exception e) {
                
          }
       ....
      //初始化仪表盘对象
      mInstrumentation.init(this, instrContext, appContext, component,
                    data.instrumentationWatcher, 		 data.instrumentationUiAutomationConnection);
      //回调Instrumentation的onCreate,实际调用的是app.onCreate
      mInstrumentation.onCreate(data.instrumentationArgs);
       ....
      //调用application的创建,并回调application的生命周期方法
      mInstrumentation.callApplicationOnCreate(app);

}

以上代码已经添加了比较详细的注释,主要做了三件事情:

1、创建仪表盘

2、使用LoadedApk创建了一个Application,最终通过反射创建了application

3、调用一些回调方法

到这里,目标进程的app初始化工作完成。

.7从AMS进程启动Activity

在AMS中调用的代码中调用了ATMS中的ActivityattachApplicationLocked中的启动Activity代码逻辑的调用: didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());

mAtmInternal:ActivityTaskManagerService:

@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
    synchronized (mGlobalLockWithoutBoost) {
        return mRootActivityContainer.attachApplication(wpc);
    }
}

调用到RootActivityContainer.attachApplication,看源码实现:

boolean attachApplication(WindowProcessController app) throws RemoteException {
    if (mStackSupervisor.realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
    return didSomething;
}

分析到这里,可以看到和之前另一个分支的逻辑基本重合了,调用到了ActivityStackSupervisor的realStartActivityLocked()方法,之后的启动流程就和前面的完全一致了。

至此,Activity的整体的启动流程就全部分析完成。

三、核心类总结

以下总结,来源官方文档注释以及个人和其它博主的理解!

**Activity:**Activity是用来和用户交互的,所以会创建window来放置Ui元素,提供给用户交互使用。

Instrumentation: 负责调用Activity和application的生命周期,在Activity启动过程中,也是跨进程调用的起点。

**ActivityTaskManagerService(ATM):**系统服务用于管理Activity,包括但不限于task、stacks、displays...。

**ActivityTaskManagerInternal:**ActivityTaskManagerService对外提供的一个抽象类,真正的实现在ActivityTaskManagerService#LocalService。

**ActivityStarter:**控制如何去启动一个Activity,会去处理intent、flags的相关内容和关联的task和stack。

**ActivityStack:**负责管理Activity的任务栈和状态处理。

ActivityStackSupervisor: 处理任务栈的监察员,涉及相关window的操作。

**ClientTransactionItem:**具体执行Activity生命周期的抽象类,基本每一个生命周期的执行,都是此类的一个实现类,比如LaunchActivityItem、PauseActivityItem。

**ClientTransaction:**持有一系列消息的容器,这些消息会被发送到客户端,其中包含callbacks列表和最终的生命周期状态。可以理解成android消息体系中的消息,实际上是被包装成了ClientTransaction。

TransactionExecutor: 按照正确的顺序执行ClientTransaction。

ClientLifecycleManage: 处理生命周期的转换请求、回调,以及将这些请求和回调作为一个独立的事务执行。正如梳理图中体现的,对LaunchActivityItem的执行触发。

扫码关注个人公众号 获取文章更新更及时: