阅读 1145

Activity 启动流程

基于Android 10源码分析

前言

Activity启动流程分析主要会以下面两个切入点进行分析

  • 整个大致启动流程的分析
  • 代码的跟踪进行流程细节分析。

由于我们AMS Activity启动流程非常的复杂,而且代码流程非常跳跃。如果直接从我们的代码进行分析会比较难理解,所以在进入代码流程分析 activity 启动过程之前,我们需要对整个启动过程要有个大概的了解,这样有助于我们对源码的分析。

AMS的启动流程请移步

Activity 启动流程 综述

如果把Activity的启动按流程差异化划分的话,可以划分为:

  • 启动的Activity 进程不存在,如Launcher 启动 app
  • 启动的Activity 进程存在

他们两者的区别就在与:

  1. AMS 判断Activity 不存在就通知Zygote进程fork 一个新的app进程;
  2. app进程启动的后,告诉AMS进程fork完成,可以进入后续启动Activity流程。

app进程启动流程简图

通信方式

Launcher启动一个新的app的时候 ,各进程之间涉及到多种通信方式。如图

Socket

上面我们可以看到SystemServer 和 Zygote 进程 是通过Socket 通信的,Zygote 在进程初始化的时候创建了本地Socket 通信服务ZygoteServer,在AMS判断Activity进程是否存在的时候,会通过socket 通知Zygote fork 进程.

//ZygoteInit.java
public static void main(String argv[]) {
    ZygoteServer zygoteServer = null;
  	Runnable caller;
    try {
    	//创建了负责与system server 进程通信的Socket服务
			zygoteServer = new ZygoteServer(isPrimaryZygote);
  		//进入Loop处理消息,如果fork了子进程则会返回一个不为Null 的 caller
  		caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        if (zygoteServer != null) {
            zygoteServer.closeServerSocket();
        }
    }
    
    // We're in the child process and have exited the select loop. Proceed to execute the
    // command.
  	// 如果caller != null 说明当前进程是子进程了,执行下面的方法进入ActivityThread.main
    if (caller != null) {
        caller.run();
    }
}
复制代码

zygoteServer.runSelectLoop()会处理各种消息包括 socket 连接 、USAP

Binder 通信

app 和 AMS 是通过Binder 进行通信的,当app进程fork之后,需要告诉AMS App进程创建成功了,并且向AMS传递IApplicationThread Binder 对象。

  1. app获取AMS binder 代理
  2. app向AMS传递ApplicationThread binder
  3. AMS 保存ApplicationThread binder Proxy 到 ProcessRecord 中
获取AMS binder 代理

因为AMS服务在初始化的时候就已经将服务注册到ServiceManager,所以可以通过ActivityManager.getService()获取IActivityManager.Stub.Proxy代理对象,然后就可以通过binder进行通信

//ActivityManager.java
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;//返回 IActivityManager.Stub.Proxy 代理对象
            }
        };
复制代码
传递 ApplicationThread Binder 对象给 AMS

ApplicationThread 继承自IApplicationThread.Stub。ApplicationThread的Binder实例在创建完成之后,并未注册到ServiceManager中,AMS无法主动获取我们IApplicationThread.Stub.Proxy 对象,所以我们必须通过传参的方式将我们的Binder传递过去。

//ActivityThread.java
@UnsupportedAppUsage
//2.创建 ApplicationThread binder
final ApplicationThread mAppThread = new ApplicationThread();
public static void main(String[] args) {
    //...
  	//1.创建ActivityThread
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
  	//....
}
private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        //...
      	//3.获取AMS binder proxy
        final IActivityManager mgr = ActivityManager.getService();
        try {
          	//4.mAppThread binder 参数 传递给AMS
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        //...
    } else {
        //不执行
    }
		//...
}
复制代码
AMS 保存ApplicationThread binder Proxy 到 ProcessRecord 中

通过binder的调用,最终进入到ActivityManagerService.attachApplication

//ActivityManagerService.java
//注意 此时的 thread 是IApplicationThread.Styb.Proxy 对象,经过Binder驱动已经帮我们转换好
public final void attachApplication(IApplicationThread thread, long startSeq) {
    //...
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
      	//1.调用attachApplicationLocked
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    }
}

private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
        int pid, int callingUid, long startSeq) {

    ProcessRecord app;
		//.... 
    try {
      	//2.AppDeathRecipient 保存 thread
        AppDeathRecipient adr = new AppDeathRecipient(
                app, pid, thread);
        thread.asBinder().linkToDeath(adr, 0);
      	//3.ProcessRecord 保存 AppDeathRecipient
        app.deathRecipient = adr;
    } catch (RemoteException e) {
      	//...
        return false;
    }
  	//...
    return true;
}

复制代码

从上面的代码我们就可以看出,AMS通过ProcessRecord 保存App 进程 ApplicationThread 的binder 代理,在之后的流程中就可以通过 ApplicationThread 的binder 代理 来跟 App进程进行通信。

其他核心数据类介绍

ProcessRecord

Android系统内部非常复杂,经层层封装后,app只需要简单的几行代码便可完成任一组件的启动/结束、 生命周期的操作。

组件启动后,首先需要依赖进程,那么就需要先创建进程,系统需要记录每个进程,这便产生了ProcessRecord。

参考链接

ActivityRecord

ActivityRecord,源码中的注释介绍:An entry in the history stack, representing an activity. 翻译:历 史栈中的一个条目,代表一个activity。

Activity的信息记录在ActivityRecord对象

ActivityStack

ActivityStack,内部维护了一个 ArrayList ,用来管理ActivityRecord

ActivityStackSupervisor

ActivityStackSupervisor,顾名思义,就是用来管理ActivityStack的

instrumentation

官方描述

instrumentation can load both a test package and the application under test into the same process. Since the application components and their tests are in the same process, the tests can invoke methods in the components, and modify and examine fields in the components.

翻译过来

Instrumentation可以把测试包和目标测试应用加载到同一个进程中运行。既然各个控件和测试代码都运行在同一个进程中了,测试代码当然就可以调用这些控件的方法了,同时修改和验证这些控件的一些数据

Android instrumentation是Android系统里面的一套控制方法或者”钩子“。这些钩子可以在正常的生命周期(正常是由操作系统控制的)之外控制Android控件的运行,其实指的就是Instrumentation类提供的各种流程控制方法,下表展示了部分方法的对应关系

MethodControl by User(Instrumentation)Control by OS
onCreatecallActivityOnCreateonCreate
onDestroycallActivityOnDestroyonDestroy
onStartcallActivityOnStartonStart

参考链接

Activity 启动的时候会通过Instrumentation 来调用 Activity的 生命周期

Activit 启动

如果把Activity 启动过程按照进程来划分的话,可以分为以下几个大步骤:

我们以 app进程A 启动 app进程B 来作为分析的例子

  • A进程向AMS发送动启动B进程 activity 的命令 (触发)
  • AMS 处理 分发启动命令 (中转)
    • if(B进程不存在) fork B 进程
      • 通知AMS B进程创建成功
    • 向B进程发送启动Activity命令
  • B进程处理AMS 启动命令 (处理)

触发 (入口)

Activity::startActivityForResult

所有的acitivity 启动最终会进入这个方法

//Activity.java
public void startActivityForResult(
        String who, Intent intent, int requestCode, @Nullable Bundle options) {
		//...
  	//通过mInstrumentation 启动Actiivity
    Instrumentation.ActivityResult ar =
        mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, who,
            intent, requestCode, options);
  	//当有返回结果需要处理
    if (ar != null) {
        mMainThread.sendActivityResult(
            mToken, who, requestCode,
            ar.getResultCode(), ar.getResultData());
    }
    //...
}
复制代码

mMainThread.getApplicationThread() 传参 ApplicationThread binder 是咧

Instrumentation::execStartActivity

public ActivityResult execStartActivity(
    Context who, IBinder contextThread, IBinder token, String target,
    Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
		//...
    try {
        intent.migrateExtraStreamToClipData(who);
        intent.prepareToLeaveProcess(who);
      	//1.获取ActivityManagerService 代理 2.启动activity
        int result = ActivityTaskManager.getService().startActivity(whoThread,
                who.getBasePackageName(), who.getAttributionTag(), intent,
                intent.resolveTypeIfNeeded(who.getContentResolver()), token, target,
                requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}
复制代码
ActivityTaskManager.getService()

Android 10开始 会将Activity启动服务逻辑从AMS 移到 ActivityTaskManagerService (后面简称 ATMS)中去。逻辑跟之前版本没差别

public static IActivityTaskManager getService() {
    return IActivityTaskManagerSingleton.get();
}

@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
        new Singleton<IActivityTaskManager>() {
            @Override
            protected IActivityTaskManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                return IActivityTaskManager.Stub.asInterface(b);
            }
        };
复制代码

中转(处理 分发启动命令)

ActivityTaskManagerService.startActivity()

public final int startActivity(IApplicationThread caller, String callingPackage,
        String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
        String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
        Bundle bOptions) {
  	//UserHandle.getCallingUserId()通过获取binder.getCallngUid来获取userId
    return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
            resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}
复制代码

ActivityTaskManagerService.startActivityAsUser()

public int startActivityAsUser(IApplicationThread caller, String callingPackage,
        String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
        String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
        Bundle bOptions, int userId) {
    return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
            resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
            true /*validateIncomingUser*/);
}

private int startActivityAsUser(IApplicationThread caller, String callingPackage,
        @Nullable String callingFeatureId, Intent intent, String resolvedType,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
    //...
		//validateIncomingUser == true 校验 userId
    userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    //构造者设计模式执行ActivityStarter.execute
    return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setCallingFeatureId(callingFeatureId)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setUserId(userId)
            .execute();
}
复制代码
getActivityStartController().checkTargetUser() (可忽略)

validateIncomingUser == true 校验 userId

ActivityStartController.checkTargetUser()

​ =>ActivityTaskManagerService.handleIncomingUser() 通过LocalServices 获取 ActivityManagerService.LocalService 实例。在AMS的启动流程中讲过LocalServices 缓存了各服务的内部实现LocalService

​ =>ActivityManagerService.LocalService.handleIncomingUser()

​ =>UserController.handleIncomingUser() 真正执行校验的地方,正常启动流程 返回 传进去的userId

ActivityStartController.obtainStarter()

这里通过工程模式创建ActivityStarter。mFactory.obtain()复用ActivityStarter减少GC频率,同Handler Message.obtain()同样的原理

ActivityStarter obtainStarter(Intent intent, String reason) {
    return mFactory.obtain().setIntent(intent).setReason(reason);
}
复制代码
ActivityStarter.execute()
int execute() {
    try {
       //...
        // If the caller hasn't already resolved the activity, we're willing
        // to do so here. If the caller is already holding the WM lock here,
        // and we need to check dynamic Uri permissions, then we're forced
        // to assume those permissions are denied to avoid deadlocking.
      	//决定可以处理该启动命令的Activity。
        if (mRequest.activityInfo == null) {
            mRequest.resolveActivity(mSupervisor);
        }

        int res;
        synchronized (mService.mGlobalLock) {
            //...
          	//开始执行请求
            res = executeRequest(mRequest);

            Binder.restoreCallingIdentity(origId);

            if (globalConfigWillChange) {
                // If the caller also wants to switch to a new configuration, do so now.
                // This allows a clean switch, as we are waiting for the current activity
                // to pause (so we will not destroy it), and have not yet started the
                // next activity.
                mService.mAmInternal.enforceCallingPermission(
                        android.Manifest.permission.CHANGE_CONFIGURATION,
                        "updateConfiguration()");
                if (stack != null) {
                    stack.mConfigWillChange = false;
                }
                if (DEBUG_CONFIGURATION) {
                    Slog.v(TAG_CONFIGURATION,
                            "Updating to new configuration after starting activity.");
                }
                mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
            }

            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
                    mLastStartActivityRecord);
            return getExternalResult(mRequest.waitResult == null ? res
                    : waitForResult(res, mLastStartActivityRecord));
        }
    } finally {
        onExecutionComplete();
    }
}
复制代码
ActivityStarter.Request.resolveActivity()
void resolveActivity(ActivityStackSupervisor supervisor) {
    //...
  	//复制一份intent,即使intent 修改 ephemeralIntent也不回变化
    ephemeralIntent = new Intent(intent);
  	//在复制一份,确保方法外的intent修改或者这边的修改不互相影响
    intent = new Intent(intent);
    //...
    // Collect information about the target of the Intent.
  	//收集可以支持的应用 Activity  比方说我们通过Intent 打开webView 如果我们收集安装了多个浏览器,那么在这句方法执行完毕之后都会被收集到Request
    activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags,
            profilerInfo);
		//...
}
复制代码
ActivityStarter.executeRequest()
private int executeRequest(Request request) {
    //...
  	//这个是查找callerApp
  	WindowProcessController callerApp = null;
    if (caller != null) {
        callerApp = mService.getProcessController(caller);
        if (callerApp != null) {
            callingPid = callerApp.getPid();
            callingUid = callerApp.mInfo.uid;
        } else {
            Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid
                    + ") when starting: " + intent.toString());
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }
  	
  	//...省略一些权限校验代码
  
  	//校验当前应用是否开启权限,我们的普通开启肯定有权限
  	boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
            requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
            request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord, resultStack);
    abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
            callingPid, resolvedType, aInfo.applicationInfo);
    abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
            callingPackage);
  
		//一个Activity 对应一个 ActiityRecord,这里创建ActiityRecord
    final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
            callingPackage, callingFeatureId, intent, resolvedType, aInfo,
            mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
            request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
            sourceRecord);
		//执行 startActivityUnchecked
    mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
            request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
            restrictedBgActivity, intentGrants);

    return mLastStartActivityResult;
}
复制代码
ActivityStarter.startActivityUnchecked()
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    int result = START_CANCELED;
    final ActivityStack startedActivityStack;
    try {
        mService.deferWindowLayout();
        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
        result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
        startedActivityStack = handleStartResult(r, result);
        mService.continueWindowLayout();
    }
    postStartActivityProcessing(r, result, startedActivityStack);
    return result;
}
复制代码
ActivityStarter.startActivityInner() 比较重要

启动模式相关处理都会在这个方法里处理

int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, Task inTask,
        boolean restrictedBgActivity, NeededUriGrants intentGrants) {
  	//设置初始化信息
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor, restrictedBgActivity);
		//判断启动模式,并且在mLaunchFlags上追加对应的标记
    computeLaunchingTaskFlags();
		//获取到Activity的启动栈
    computeSourceStack();
		//根据上面的计算,设置应用识别到的flags
    mIntent.setFlags(mLaunchFlags);
	
  	//...省略一些activityTask 操作代码

    mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(),
            newTask, mKeepCurTransition, mOptions);
    if (mDoResume) {//处理完启动栈的任务栈的问题后,准备执行发起者的Resume状态了
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
        if (!mTargetStack.isTopActivityFocusable()
                || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                && mStartActivity != topTaskActivity)) {
            // If the activity is not focusable, we can't resume it, but still would like to
            // make sure it becomes visible as it starts (this will also trigger entry
            // animation). An example of this are PIP activities.
            // Also, we don't want to resume activities in a task that currently has an overlay
            // as the starting activity just needs to be in the visible paused state until the
            // over is removed.
            // Passing {@code null} as the start parameter ensures all activities are made
            // visible.
            mTargetStack.ensureActivitiesVisible(null /* starting */,
                    0 /* configChanges */, !PRESERVE_WINDOWS);
            // Go ahead and tell window manager to execute app transition for this activity
            // since the app transition will not be triggered through the resume channel.
            mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
        } else {
            // If the target stack was not previously focusable (previous top running activity
            // on that stack was not visible) then any prior calls to move the stack to the
            // will not update the focused stack.  If starting the new activity now allows the
            // task stack to be focusable, then ensure that we now update the focused stack
            // accordingly.
            if (mTargetStack.isTopActivityFocusable()
                    && !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityInner");
            }
          	//从这里开始resume我们的mStartActivity
            mRootWindowContainer.resumeFocusedStacksTopActivities(
                    mTargetStack, mStartActivity, mOptions);
        }
    }
    mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);

    // Update the recent tasks list immediately when the activity starts
    mSupervisor.mRecentTasks.add(mStartActivity.getTask());
    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(),
            mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetStack);

    return START_SUCCESS;
}
复制代码

RootWindowContainer.resumeFocusedStacksTopActivities()

​ =>ActivityStack.resumeTopActivityUncheckedLocked()

​ =>ActivityStack.resumeTopActivityInnerLocked() resume Activity 最终的执行在这个方法中

ActivityStack.resumeTopActivityInnerLocked() 比较重要
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    
  	//...
  	//尝试将发起者置入Pause状态 pausing == true 说明确实需要pause
    boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next);
    //...省略代码,这里会根据pausing 做一些操作
		//...
    if (next.attachedToProcess()) {
      	//...
    } 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 */);
            }
        }
      	//启动具体Activity
        mStackSupervisor.startSpecificActivity(next, true, true);
    }
    return true;
}
复制代码
ActivityStackSupervisor.startSpecificActivity()
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
  	//获取目标进程
    final WindowProcessController wpc =
            mService.getProcessController(r.processName, r.info.applicationInfo.uid);

    boolean knownToBeDead = false;
    if (wpc != null && wpc.hasThread()) {
        try {
          	//如果进程存在则进入后续流程
            realStartActivityLocked(r, wpc, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }

        // If a dead object exception was thrown -- fall through to
        // restart the application.
        knownToBeDead = true;
    }

    r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

    final boolean isTop = andResume && r.isTopRunningActivity();
  	//如果进程不存在则异步开启进程
    mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
复制代码

小结

虽然前面的流程非常的绕,但是总结一下就是进行启动Activity一些列校验,如果满足条件就进入后面fork 进程 或者直接启动目标进程的Activity

ActivityTaskManagerService.startProcessAsync()

void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
        String hostingType) {
    try {
        if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"
                    + activity.processName);
        }
        // Post message to start process to avoid possible deadlock of calling into AMS with the
        // ATMS lock held.
      	//通过handle 发送执行函数 ActivityManagerInternal::startProcess
        final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
                mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
                isTop, hostingType, activity.intent.getComponent());
        mH.sendMessage(m);
    } finally {
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }
}
复制代码

ActivityManagerService.LocalService.startProcess()

​ =>ActivityManagerService.startProcess.startProcessLocked()

​ =>ProcessList.startProcessLocked()

ProcessList.startProcessLocked()
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
        int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
        boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs,
        Runnable crashHandler) {
    long startTime = SystemClock.uptimeMillis();
    ProcessRecord app;

  	//....

    if (app == null) {//执行这里
        checkSlow(startTime, "startProcess: creating new process record");
      	//new 一个ProcessRecord   isolated == false
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
        if (app == null) {
            Slog.w(TAG, "Failed making new process record for "
                    + processName + "/" + info.uid + " isolated=" + isolated);
            return null;
        }
        app.crashHandler = crashHandler;
        app.isolatedEntryPoint = entryPoint;
        app.isolatedEntryPointArgs = entryPointArgs;
        if (precedence != null) {
            app.mPrecedence = precedence;
            precedence.mSuccessor = app;
        }
        checkSlow(startTime, "startProcess: done creating new process record");
    } else {
        //....
    }
		//...
  	//
    final boolean success =
            startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
    return success ? app : null;
}
复制代码
ProcessList.newProcessRecordLocked()
final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
        boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
    String proc = customProcess != null ? customProcess : info.processName;
    final int userId = UserHandle.getUserId(info.uid);
    int uid = info.uid;
    if (isolated) {
        //..... isolated == false 不执行这里
    }
    final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
		//...省略初始化ProcessRecord代码
  	//将我们的ProcessRecord 添加到 mProcessNames 集合中,方便获取
    addProcessNameLocked(r);
    return r;
}
复制代码
ProcessList.startProcessLocked()
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
        int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
  	//...参数的一些初始化

    if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
      	//这里异步执行,一般不会走这里
        mService.mProcStartHandler.post(() -> handleProcessStart(
                app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
                requiredAbi, instructionSet, invokeWith, startSeq));
        return true;
    } else {
        try {
            final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                    entryPoint, app,
                    uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
                    requiredAbi, instructionSet, invokeWith, startTime);
            handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                    startSeq, false);
        } catch (RuntimeException e) {
          //....启动失败
        }
        return app.pid > 0;
    }
}
复制代码
ProcessList.startProcess()
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
        int mountExternal, String seInfo, String requiredAbi, String instructionSet,
        String invokeWith, long startTime) {
    try {
        //...
        final Process.ProcessStartResult startResult;
        if (hostingRecord.usesWebviewZygote()) {// 使用webView的Zygote,代码不执行这里
            startResult = startWebView(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, null, app.info.packageName, app.mDisabledCompatChanges,
                    new String[]{PROC_START_SEQ_IDENT + app.startSeq});
        } else if (hostingRecord.usesAppZygote()) {// 使用AppZygote,代码执行这里 
          	
            final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

            // We can't isolate app data and storage data as parent zygote already did that.
            startResult = appZygote.getProcess().start(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, null, app.info.packageName,
                    /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
                    app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
                    false, false,
                    new String[]{PROC_START_SEQ_IDENT + app.startSeq});
        } 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, zygotePolicyFlags,
                    isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
                    whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
                    new String[]{PROC_START_SEQ_IDENT + app.startSeq});
        }
        return startResult;
    } finally {
      	//....
    }
}
复制代码

appZygote.getProcess().start() == ZygoteProcess.start()

​ =>ZygoteProcess.startViaZygote() 方法会调用 openZygoteSocketIfNeeded(abi)方法 开启ZygoteSocket

​ =>ZygoteProcess.zygoteSendArgsAndGetResult()

​ =>ZygoteProcess.attemptZygoteSendArgsAndGetResult()

通过Socket 通知ZygoteServer开始启动服务

ZygoteServer.runSelectLoop()

处理socket 连接

Runnable runSelectLoop(String abiList) {
  	//socket 文件描述符
    ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
  	//socket 连接
    ArrayList<ZygoteConnection> peers = new ArrayList<>();
    socketFDs.add(mZygoteSocket.getFileDescriptor());
    peers.add(null);
    //...
    while (true) {
      	StructPollfd[] pollFDs;
      	// Allocate enough space for the poll structs, taking into account
         // the state of the USAP pool for this Zygote (could be a
         // regular Zygote, a WebView Zygote, or an AppZygote).
         if (mUsapPoolEnabled) {
             usapPipeFDs = Zygote.getUsapPipeFDs();
             pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length];
         } else {
             pollFDs = new StructPollfd[socketFDs.size()];
         }

         /*
          * For reasons of correctness the USAP pool pipe and event FDs
          * must be processed before the session and server sockets.  This
          * is to ensure that the USAP pool accounting information is
          * accurate when handling other requests like API deny list
          * exemptions.
          */

         int pollIndex = 0;
         for (FileDescriptor socketFD : socketFDs) {
             pollFDs[pollIndex] = new StructPollfd();
             pollFDs[pollIndex].fd = socketFD;
             pollFDs[pollIndex].events = (short) POLLIN;
             ++pollIndex;
         }

         final int usapPoolEventFDIndex = pollIndex;
        //...
        int pollReturnValue;
        try {
          	//这里会阻塞,等待 pollTimeoutMs超时时长。
            pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
        } catch (ErrnoException ex) {
            throw new RuntimeException("poll failed", ex);
        }
        if (pollReturnValue == 0) {
          //... 超时
        } else {
          	//处理所有可能FD 指令
            while (--pollIndex >= 0) {
                if ((pollFDs[pollIndex].revents & POLLIN) == 0) {//说明FD没有需要执行的指令
                    continue;
                }

                if (pollIndex == 0) {
                    // Zygote server socket
										//有新的socket 连接指令,创建连接
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                  	//添加socket连接
                    peers.add(newPeer);
                  	//添加fd 到socketFDs
                    socketFDs.add(newPeer.getFileDescriptor());
                } else if (pollIndex < usapPoolEventFDIndex) {
                    //收到fork指令
                    try {
                        ZygoteConnection connection = peers.get(pollIndex);
                      	//执行fork操作,如果是子进程 command 不为空,command.run 会执行到ActivityThread.main
                        final Runnable command = connection.processOneCommand(this);
												//connection.processOneCommand(this) 如果是子进程 会将mIsForkChild设置为true
                        if (mIsForkChild) {
                            if (command == null) {
                                throw new IllegalStateException("command == null");
                            }
                            return command;
                        } else {
                            if (command != null) {
                                throw new IllegalStateException("command != null");
                            }
                            if (connection.isClosedByPeer()) {
                                connection.closeSocket();
                                peers.remove(pollIndex);
                                socketFDs.remove(pollIndex);
                            }
                        }
                    } catch (Exception e) {
                        if (!mIsForkChild) {
                            ZygoteConnection conn = peers.remove(pollIndex);
                            conn.closeSocket();
                            socketFDs.remove(pollIndex);
                        } else {
                            throw e;
                        }
                    } finally {
                      	//还原mIsForkChild
                        mIsForkChild = false;
                    }
                } else {
                    //...
                }
            }
            //...
        }
        //...
    }
}
复制代码
ZygoteConnection.processOneCommand

fork 进程的地方

Runnable processOneCommand(ZygoteServer zygoteServer) {
		//....
    int pid = -1;
    ...
    //Fork子进程,得到一个新的pid
    /fork子进程,采用copy on write方式,这里执行一次,会返回两次
    ///pid=0 表示Zygote  fork子进程成功
    //pid > 0 表示子进程 的真正的PID

    pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
            parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
            parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
            parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
            parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
            parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);

    try {
        if (pid == 0) {
            // in child
            zygoteServer.setForkChild();

            zygoteServer.closeServerSocket();
            IoUtils.closeQuietly(serverPipeFd);
            serverPipeFd = null;

            return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
        } else { //Zygote 进程
            // In the parent. A pid < 0 indicates a failure and will be handled in
            // handleParentProc.
            IoUtils.closeQuietly(childPipeFd);
            childPipeFd = null;
            handleParentProc(pid, serverPipeFd);
            return null;
        }
    } finally {
      	//...
    }
}
复制代码

ZygoteConnection.handleChildProc()

​ =>ZygoteInit.zygoteInit()

​ =>RuntimeInit.applicationInit()

​ =>RuntimeInit.findStaticMain()

​ =>RuntimeInit.MethodAndArgsCaller() 返回执行ActivityThread.main() 的Runnable

​ =>ActivityThread.main()

​ =>ActivityThread.attach()

​ =>ActivityManagerService.attachApplication()

​ =>ActivityManagerService.attachApplicationLocked()

ActivityManagerService.attachApplication()
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
    ProcessRecord app;
		//...
  	//mProcessesReady这个变量在AMS的 systemReady 中被赋值为true,
    //所以这里的normalMode也为true
    boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   	//...
    if (normalMode) {
        try {
          	//mAtmInternal == LocalServices.getService(ActivityTaskManagerInternal.class);
          	//最终会执行ActivityTaskManagerService.LocalService.attachApplication()
            didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
        } catch (Exception e) {
          	//...
        }
    }
		//...
    return true;
}
复制代码

ActivityTaskManagerService.LocalService.attachApplication()

​ =>WindowManagerService.mRoot.attachApplication() == RootWindowContainer.attachApplication()

RootWindowContainer.attachApplication()
boolean attachApplication(WindowProcessController app) throws RemoteException {
    final String processName = app.mName;
    boolean didSomething = false;
    for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
        final DisplayContent display = getChildAt(displayNdx);
        final ActivityStack stack = display.getFocusedStack();
        if (stack == null) {
            continue;
        }

        mTmpRemoteException = null;
        mTmpBoolean = false; // Set to true if an activity was started.
        final PooledFunction c = PooledLambda.obtainFunction(
                RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
                PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());
      	//执行WindowContainer.forAllActivities()
        stack.forAllActivities(c);
        c.recycle();
        if (mTmpRemoteException != null) {
            throw mTmpRemoteException;
        }
        didSomething |= mTmpBoolean;
    }
  	//...
    return didSomething;
}
复制代码

WindowContainer.forAllActivities() 方法最总调用 RootWindowContainer::startActivityForAttachedApplicationIfNeeded

RootWindowContainer.startActivityForAttachedApplicationIfNeeded()
private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
        WindowProcessController app, ActivityRecord top) {
    //...

    try {
      	//执行ActivityStackSupervisor.realStartActivityLocked() 
        if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
                true /*checkConfig*/)) {
            mTmpBoolean = true;
        }
    } catch (RemoteException e) {
       	//...
        return true;
    }
    return false;
}
复制代码

ActivityStackSupervisor.startSpecificActivity() 方法里面如果进程存在也是执行的ActivityStackSupervisor.realStartActivityLocked() ,所以创建进程绕了一大圈后面的流程又一致了开始真正的开启Activity了

ActivityStackSupervisor.realStartActivityLocked()

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
		//...
    try {
        //....
        try {
						// Create activity launch transaction.
          	//创建ClientTransaction
            final ClientTransaction clientTransaction = ClientTransaction.obtain(
                    proc.getThread(), r.appToken);

            final DisplayContent dc = r.getDisplay().mDisplayContent;
          	//clientTransaction 添加回调
            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.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                    dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                    r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));

            // Set desired final state.
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            clientTransaction.setLifecycleStateRequest(lifecycleItem);

            // Schedule transaction.
          	//执行我们的transaction
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);
						//...
        } catch (RemoteException e) {
            //....
        }
    } finally {
        //...
    }
		//...
    return true;
}
复制代码
ClientLifecycleManagerscheduleTransaction()
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
  	//开始跨进程调用了
    transaction.schedule();
    if (!(client instanceof Binder)) {
        transaction.recycle();
    }
}
复制代码
ClientTransaction.schedule()
public void schedule() throws RemoteException {
  	//mClient 是 ApplicationThread binder的代理
    mClient.scheduleTransaction(this);
}
复制代码

处理 (结束)

ApplicationThread.scheduleTransaction()

​ =>ActivityThread.scheduleTransaction() == ClientTransactionHandler.scheduleTransaction() ActivityThread 继承 ClientTransactionHandler

ClientTransactionHandler.scheduleTransaction()

void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
  	//通过Handler 切换到主线程处理 EXECUTE_TRANSACTION 事件
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
复制代码

H.handleMessage()

public void handleMessage(Message msg) {
    switch (msg.what) {
        case EXECUTE_TRANSACTION:
            final ClientTransaction transaction = (ClientTransaction) msg.obj;
        		//接下来的代码就是在主线程里面了
            mTransactionExecutor.execute(transaction);
            if (isSystem()) {
                transaction.recycle();
            }
            break;
    }
}
复制代码

TransactionExecutor.execute()

​ =>TransactionExecutor.executeCallbacks()

TransactionExecutor.executeCallbacks()

public void executeCallbacks(ClientTransaction transaction) {
  	//这里的callbacks集合是我们要执行的
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
    if (callbacks == null || callbacks.isEmpty()) {
        return;
    }
		//...
    final int size = callbacks.size();
    for (int i = 0; i < size; ++i) {
        final ClientTransactionItem item = callbacks.get(i);
      	//可能大家会有疑问,接下来该怎么走。这要回到ActivityStackSupervisor.realStartActivityLocked()方法 我们添加的LaunchActivityItem callback,所以下面会执行到 LaunchActivityItem.execute
        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
    }
}
复制代码

LaunchActivityItem.execute()

public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
            mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
            mPendingResults, mPendingNewIntents, mIsForward,
            mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
  	// client 就是ActivityThread 所以进入了我们熟悉的代码了
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}
复制代码

总结

Acitivity启动过程错综复杂,需要对他们整个流程有个大概的认识之后才能在这些代码跳转中不会绕晕。总之Activity启动流程到这里就结束了,这里面很多其他的小细节由于篇幅问题并没有展开太多。

文章分类
Android
文章标签