AMS流程分析

1.流程图

2.主要的几个类
  • Activity

       窗口活动,四大组件之一,可以与用户进行交互的页面,运行在App客户端进程;Activity有自己的窗口大小,全屏或者部分窗口,可以配置启动模式LaunchMode以及启动时配置的Flag等,还可以配置栈taskAffinity属性 

  • ActivityManagerService

        Binder跨进程的服务端,面向外部提供一系列的接口,主要是负责接收外部调用,预处理部分数据,真正的执行逻辑是交给ActivityStarter去处理

  • ActivityTaskManagerService

        Android核心服务,负责四大组件的启动,切换,调度等工作

  • ApplicationThread

        ActivityThread的一个内部类,继承IApplicationThread.Stub,是一个IBinder,是ActiivtyThread于ASM通信的桥梁

  • ActivityRecord

        运行在AMS服务端进程,记录一个Activity的相关信息,包括但不仅限于其包名、Activity名字、进程信息、启动Intent、运行状态等信息,还有它属于哪个栈TaskRecord、以及它的线程信息ProcessRecord;
它里面有一个重要的appToken成员,是一个唯一标识量,客户端和服务端都根据这个标识来确定对应的ActivityRecord或ActivityClientRecord,所以涉及到Activity信息相关的东西,在AMS和App进程之间不传用Activity来传递,一般都是由appToken来传递确定

  • TaskRecord

        运行在AMS服务端进程,组织管理许多ActivityRecord,它就是我们俗称的Activity栈,它由自己的id、名字(affinity)以及它属于哪个ActivityStack管理等等信息

  • ClientLifecycleManager

        管理 Activity 生命周期

  • ActivityStack

        运行在AMS服务端进程,负责单个Activity栈的状态和管理,它管理了许多TaskRecord

  • ActivityStackSupervisor

        ActivityStack的管理者,管理了系统中所有的ActivityStack。它负责所有Activity栈的管理

  • ActivityStarter

        真正的业务处理类,它会组织以上所有的类进行业务调用、处理等

  • ActivityThread

        客户端进程的入口类,入口方法为main方法;startActivity时,AMS判断启动目标Activity还没有进程,会以LocalSocket方法向zygote孵化器发起创建进程请求,zygote根据自身创建好进程后,会议ActivityThread的main作为入口开始执行,这样一个App进程就开始执行了
在ActivityThread内部有一个内部类ApplicationThread,它是一个IApplicationThread.Stub类型,也就是一个Binder类,在上诉main方法中,会调用AMS的attachApplication将这个ActivityThread绑定到ProcessRecord上去,这样客户端和服务端App都对应匹配上了

  • Instrumentation

        Activity生命周期类负责的类,四大组件的生命周期几乎都是由它来控制的

  • ProcessRecord

        记录一个进程信息,包含进程名、IApplicationThread客户端线程、uid、线程状态等相关信息,通常保存在AMS服务端,客户端访问服务端时,通过客户端的pid可以获取对应的ProcessRecord,进而可以知道向哪个客户端发起调用

3.App的启动流程

点击Launcher上的App图标时,会调用startActivitySafely方法

packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
@Override
public boolean startActivitySafely(View v, Intent intent, ItemInfo item,
        @Nullable String sourceContainer) {
    if (!hasBeenResumed()) {
        // Workaround an issue where the WM launch animation is clobbered when finishing the
        // recents animation into launcher. Defer launching the activity until Launcher is
        // next resumed.
        addOnResumeCallback(() -> startActivitySafely(v, intent, item, sourceContainer));
        if (mOnDeferredActivityLaunchCallback != null) {
            mOnDeferredActivityLaunchCallback.run();
            mOnDeferredActivityLaunchCallback = null;
        }
        return true;
    }
 
    boolean success = super.startActivitySafely(v, intent, item, sourceContainer);
    if (success && v instanceof BubbleTextView) {
        // This is set to the view that launched the activity that navigated the user away
        // from launcher. Since there is no callback for when the activity has finished
        // launching, enable the press state and keep this reference to reset the press
        // state when we return to launcher.
        BubbleTextView btv = (BubbleTextView) v;
        btv.setStayPressed(true);
        addOnResumeCallback(btv);
    }
    return success;
}

intent中携带App的关键信息也就是Manifest.xml配置文件中配置的默认启动页信息,这个在应用安装的时候,Launcher就已经将启动信息记录下来了,图标只是一个快捷方式的入口。

然后startActivitySafely的方法最终会调用Activity里的startActivity方法.

frameworks/base/core/java/android/app/Activity.java
@Override
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的方法中code为-1,表示startActivity并不关心是否启动成功。startActivityForResult部分方法如下所示:

frameworks/base/core/java/android/app/Activity.java
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
         @Nullable Bundle options) {
     if (mParent == null) {//mParent是Activity类型,表示如果此视图是嵌入的子视图,则返回mParent Activity。
         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());
         }
         if (requestCode >= 0) {//上面说过,requestCode传进来的值为-1,此处不会调用
             // If this start is requesting a result, we can avoid making
             // the activity visible until the result is received.  Setting
             // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
             // activity hidden during this time, to avoid flickering.
             // This can only be done when a result is requested because
             // that guarantees we will get information back when the
             // activity is finished, no matter what happens to it.
             mStartedActivity = true;
         }
 
         cancelInputsAndStartExitTransition(options);
         // TODO Consider clearing/flushing other event sources and events for child windows.
     } else {
         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方法中又会调用mInstrumentation.execStartActivity方法。这里会传入两个比较重要的参数

mMainThread.getApplicationThread():得到的是一个Binder对象,代表Launcher所在的App的进程。

mToken:它是一个Binder代理对象,指向了AMS 中一个类型为 ActivityRecord的Binder本地对象,用来维护对应的Activity组件的运行状态以及信息。Activity.java的mToken,传到Instrumentation.java的token,然后到了ActivityTaskManagerService.java传给了resultTo。如果ActivityA启动ActivityB(startActivity(new Intent(ActivityA.this,ActivityB.class)); ),通过加log发现这个resultTo就是ActivityA。

然后再看一下Instrumentation.execStartActivity方法:

frameworks/base/core/java/android/app/Instrumentation.java
@UnsupportedAppUsage
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    if (referrer != null) {
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
    if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i=0; i<N; i++) {
                final ActivityMonitor am = mActivityMonitors.get(i);
                ActivityResult result = null;
                if (am.ignoreMatchingSpecificIntents()) {
                    result = am.onStartActivity(intent);
                }
                if (result != null) {
                    am.mHits++;
                    return result;
                } else if (am.match(who, null, intent)) {
                    am.mHits++;
                    if (am.isBlocking()) {
                        return requestCode >= 0 ? am.getResult() : null;
                    }
                    break;
                }
            }
        }
    }
    try {
        intent.migrateExtraStreamToClipData(who);
        intent.prepareToLeaveProcess(who);
        int result = ActivityTaskManager.getService().startActivity(whoThread,
                who.getBasePackageName(), who.getAttributionTag(), 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;
}

Instrumentation这个类就是一个可以对Application和Activity初始化和生命周期调用的工具类,用来监控系统与应用的交互。这个方法里主要就是调用ActivityTaskManager.getService().startActivity方法

通过通过单例模式获取ActivityTaskManagerService

core/java/android/app/ActivityTaskManager.java
/** @hide */
 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);//获取到ActivityTaskManagerService
                 return IActivityTaskManager.Stub.asInterface(b);
             }
         };

获取到的就是ActivityTaskManagerService(ATMS),ActivityTaskManagerService这个类负责四大组件的启动,切换,调度等工作。回到上面startActivity方法

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
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) {
    return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
            resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}
 
 
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) {
    assertPackageMatchesCallingUid(callingPackage);
    enforceNotIsolatedCaller("startActivityAsUser");
 
    userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
 
    // TODO: Switch to user app stacks here.
    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().obtainStarter获取到一个ActivityStarter对象,ActivityStarter是启动活动的控制器,一些主要的逻辑都写在这里。然后设置一些信息,接着调用ActivityStarter的execute()方法执行启动activity的一些逻辑。

frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
    try {
        // Refuse possible leaked file descriptors
        if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
 
        final LaunchingState launchingState;
        synchronized (mService.mGlobalLock) {
            final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);//创建ActivityRecord对象,是AMS中保存activity信息的数据结构,AMS就是通过这一个结构来管理activity的
            launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
                    mRequest.intent, caller);
        }
 
        // 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.
        if (mRequest.activityInfo == null) {
            mRequest.resolveActivity(mSupervisor);
        }
 
        int res;
        synchronized (mService.mGlobalLock) {
            final boolean globalConfigWillChange = mRequest.globalConfig != null
                    && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
            final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
            if (stack != null) {
                stack.mConfigWillChange = globalConfigWillChange;
            }
            if (DEBUG_CONFIGURATION) {
                Slog.v(TAG_CONFIGURATION, "Starting activity when config will change = "
                        + globalConfigWillChange);
            }
 
            final long origId = Binder.clearCallingIdentity();
 
            res = resolveToHeavyWeightSwitcherIfNeeded();
            if (res != START_SUCCESS) {
                return res;
            }
            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);
            }
 
            // Notify ActivityMetricsLogger that the activity has launched.
            // ActivityMetricsLogger will then wait for the windows to be drawn and populate
            // WaitResult.
            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
                    mLastStartActivityRecord);
            return getExternalResult(mRequest.waitResult == null ? res
                    : waitForResult(res, mLastStartActivityRecord));
        }
    } finally {
        onExecutionComplete();
    }
}

在这个方法中会根据前面提供的一些参数解析必要的信息,执行开始活动的请求。主要调用executeRequest方法:

frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int executeRequest(Request request) {
    if (TextUtils.isEmpty(request.reason)) {
        throw new IllegalArgumentException("Need to specify a reason.");
    }
    ......
 
    mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
            request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
            restrictedBgActivity, intentGrants);
 
    if (request.outActivity != null) {
        request.outActivity[0] = mLastStartActivityRecord;
    }
 
    return mLastStartActivityResult;
}

在这个方法中执行Activity启动请求,开始启动Activity。 前面是执行几个初步检查。 后面Activity的启动流程将分别调用startActivityUnchecked→startActivityInner

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);//初始化状态
 
    computeLaunchingTaskFlags();//根据launchMode和Intent中的FLAG_ACTIVITY_NEW_TASK等flag综合计算Activity 的启动模式,结果保存在mLaunchFlags 中
 
    computeSourceStack();//根据ActivityRecord:mSourceRecord来找到源任务栈:mSourceTask
 
    mIntent.setFlags(mLaunchFlags); // 设置刚才在上面计算出来的mLaunchFlags
 
    final Task reusedTask = getReusableTask();//获得可以重用的task
 
    // If requested, freeze the task list
    if (mOptions != null && mOptions.freezeRecentTasksReordering()
            && mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid)
            && !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) {
        mFrozeTaskList = true;
        mSupervisor.mRecentTasks.setFreezeTaskListReordering();
    }
 
    //查找是否栈中已有可复用的activity:如果没有,并且没有对应合适的栈,那么就要将newTask置true,到时候创建新的栈.第一次启动,所以reusedTask==null,newTask=true
    final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
    final boolean newTask = targetTask == null;
    mTargetTask = targetTask;
 
    computeLaunchParams(r, sourceRecord, targetTask);
 
    // Check if starting activity on given task or on a new task is allowed.
    int startResult = isAllowedToStart(r, newTask, targetTask);//检查activity是否允许被启动
    if (startResult != START_SUCCESS) {
        return startResult;
    }
 
    final ActivityRecord targetTaskTop = newTask
            ? null : targetTask.getTopNonFinishingActivity();//获取ActivityRecord.
    if (targetTaskTop != null) {
        // Recycle the target task for this launch.
        startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);//准备要为本次启动重用的task
        if (startResult != START_SUCCESS) {
            return startResult;
        }
    } else {
        mAddingToTask = true;
    }
 
    // 如果正在启动的Activity与当前位于顶部的Activity相同,需要检查它是否应该只启动一次。即singletop启动模式
    final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
    if (topStack != null) {
        startResult = deliverToCurrentTopIfNeeded(topStack, intentGrants);
        if (startResult != START_SUCCESS) {
            return startResult;
        }
    }
 
    if (mTargetStack == null) {//如果目标task为空,新建一个task
        mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, targetTask, mOptions);
    }
    if (newTask) {//这里是判断是加入新的栈还是加入已有的栈,第一次启动newTask为true
        final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                ? mSourceRecord.getTask() : null;
        setNewTask(taskToAffiliate);
        if (mService.getLockTaskController().isLockTaskModeViolation(
                mStartActivity.getTask())) {
            Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
            return START_RETURN_LOCK_TASK_MODE_VIOLATION;
        }
    } else if (mAddingToTask) {
        addOrReparentStartingActivity(targetTask, "adding to task");
    }
 
    if (!mAvoidMoveToFront && mDoResume) {
        //移动到栈顶
        mTargetStack.getStack().moveToFront("reuseOrNewTask", targetTask);
        if (mOptions != null) {
            if (mOptions.getTaskAlwaysOnTop()) {
                mTargetStack.setAlwaysOnTop(true);
            }
        }
        if (!mTargetStack.isTopStackInDisplayArea() && mService.mInternal.isDreaming()) {
            // Launching underneath dream activity (fullscreen, always-on-top). Run the launch-
            // -behind transition so the Activity gets created and starts in visible state.
            mLaunchTaskBehind = true;
            r.mLaunchTaskBehind = true;
        }
    }
 
    mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
            mStartActivity.getUriPermissionsLocked());//权限检查
    if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) {
        // we need to resolve resultTo to a uid as grantImplicitAccess deals explicitly in UIDs
        final PackageManagerInternal pmInternal =
                mService.getPackageManagerInternalLocked();
        final int resultToUid = pmInternal.getPackageUidInternal(
                        mStartActivity.resultTo.info.packageName, 0, mStartActivity.mUserId);
        pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent,
                UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/,
                resultToUid /*visible*/, true /*direct*/);
    }
    if (newTask) {
        EventLogTags.writeWmCreateTask(mStartActivity.mUserId,
                mStartActivity.getTask().mTaskId);
    }
    mStartActivity.logStartActivity(
            EventLogTags.WM_CREATE_ACTIVITY, mStartActivity.getTask());
 
    mTargetStack.mLastPausedActivity = null;
 
    mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(
            false /* forceSend */, mStartActivity);
 
    mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(),
            newTask, mKeepCurTransition, mOptions);
    if (mDoResume) {
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
        if (!mTargetStack.isTopActivityFocusable()
                || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                && mStartActivity != topTaskActivity)) {//如果当前的activity没有焦点,我们仍然需要确保它可见
            mTargetStack.ensureActivitiesVisible(null /* starting */,
                    0 /* configChanges */, !PRESERVE_WINDOWS);
            mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
        } else {
            if (mTargetStack.isTopActivityFocusable()
                    && !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityInner");
            }
            mRootWindowContainer.resumeFocusedStacksTopActivities(
                    mTargetStack, mStartActivity, mOptions);//开始暂停上一个activity
        }
    }
    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;
}

这个方法主要就是进行一些检查及task分配工作。然后调用RootWindowContainer.resumeFocusedStacksTopActivities开始进项上一个activity的pause工作

frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
    boolean resumeFocusedStacksTopActivities(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
 
    if (!mStackSupervisor.readyToResume()) {
        return false;
    }
 
    boolean result = false;
    if (targetStack != null && (targetStack.isTopStackInDisplayArea()
            || getTopDisplayFocusedStack() == targetStack)) {
        result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    ......
    return result;
}

接着调用ActivityStack的resumeTopActivityUncheckedLocked方法->resumeTopActivityInnerLocked方法。ActivityStack负责单个Activity栈的状态和管理。

frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
        // Not ready yet!
        return false;
    }
    ......
    if (mResumedActivity != null) {
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Pausing " + mResumedActivity);
        pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);//一:将activity onPause
    }
    ......
        mStackSupervisor.startSpecificActivity(next, true, true);//二:继续启动
    }
 
    return true;
}

resumeTopActivityInnerLocked方法主要是先将上一个activity pause,然后接续启动。首先看pause activity的部分。

(1)通过startPausingLocked()方法先pause activity。这个函数是暂停pause(如此处的是上一个应用launcher),设置当前状态为pausing

ActivityStack
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
        ActivityRecord resuming) {
    if (mPausingActivity != null) {//第一次进来mPausingActivity是null,应用没有暂停就没有mPausingActivity
        Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
                + " state=" + mPausingActivity.getState());
        if (!shouldSleepActivities()) {
            // Avoid recursion among check for sleep and complete pause during sleeping.
            // Because activity will be paused immediately after resume, just let pause
            // be completed by the order of activity paused from clients.
            completePauseLocked(false, resuming);
        }
    }
    ActivityRecord prev = mResumedActivity;//mResumedActivity是当前resume的activity,此处是launcher
 
    if (prev == null) {
        if (resuming == null) {
            Slog.wtf(TAG, "Trying to pause when nothing is resumed");
            mRootWindowContainer.resumeFocusedStacksTopActivities();
        }
        return false;
    }
 
    if (prev == resuming) {
        Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
        return false;
    }
 
    if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
    else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
    mPausingActivity = prev;//launcher设置为正在pause的进程
    mLastPausedActivity = prev;//设置上一个暂停的应用
    mLastNoHistoryActivity = prev.isNoHistory() ? prev : null;
    prev.setState(PAUSING, "startPausingLocked");//标定该进程在PAUSING状态
    prev.getTask().touchActiveTime();
    clearLaunchTime(prev);
 
    mAtmService.updateCpuStats();//pause应用会触发cpu状态更新
 
    boolean pauseImmediately = false;
    if (resuming != null && (resuming.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0) {
        // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous
        // activity to be paused, while at the same time resuming the new resume activity
        // only if the previous activity can't go into Pip since we want to give Pip
        // activities a chance to enter Pip before resuming the next activity.
        final boolean lastResumedCanPip = prev != null && prev.checkEnterPictureInPictureState(
                "shouldResumeWhilePausing", userLeaving);
        if (!lastResumedCanPip) {
            pauseImmediately = true;
        }
    }
 
    if (prev.attachedToProcess()) {//prev是launcher,所以已经有关联的进程,此处会进入
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
        try {
            EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
                    prev.shortComponentName, "userLeaving=" + userLeaving);
 
            mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                    prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately));//此处才是activity的真正的pause执行的地方
        } catch (Exception e) {
            // Ignore exception, if process died other code will cleanup.
            Slog.w(TAG, "Exception thrown during pause", e);
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }
    } else {
        mPausingActivity = null;
        mLastPausedActivity = null;
        mLastNoHistoryActivity = null;
    }
 
    // If we are not going to sleep, we want to ensure the device is
    // awake until the next activity is started.
    if (!uiSleeping && !mAtmService.isSleepingOrShuttingDownLocked()) {
        mStackSupervisor.acquireLaunchWakelock();
    }
 
    if (mPausingActivity != null) {//mPausingActivity就是launcher,所以会进来此处。
        if (!uiSleeping) {
            prev.pauseKeyDispatchingLocked();//应用的pause的时候,会暂停接收输入事件,此时系统触摸不会反馈给上层
        } else if (DEBUG_PAUSE) {
             Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
        }
 
        if (pauseImmediately) {//快速pause 不等待pause
            // If the caller said they don't want to wait for the pause, then complete
            // the pause now.
            completePauseLocked(false, resuming);
            return false;
 
        } else {
            prev.schedulePauseTimeout(); //设置pause的超时时间500s
            return true;
        }
 
    } else {
        // This activity failed to schedule the
        // pause, so just treat it as being paused now.
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
        if (resuming == null) {
            mRootWindowContainer.resumeFocusedStacksTopActivities();
        }
        return false;
    }
}

看一下activity的真正的pause执行的地方:在ClientLifecycleManager.java的scheduleTransaction()方法里。ClientLifecycleManager 是管理 Activity 生命周期的,这里会传入PauseActivityItem给ClientLifecycleManager来进行pause。

ResumeActivityItem,PauseActivityItem,StopActivityItem,DestroyActivityItem 四个类继承实现了 ActivityLifecycleItem,用来实现对 Activity 生命周期的调度。他们都是通过调用 ActivityThread 的相关函数实现对 Activity 生命周期函数的调用

PauseActivityItem
@Override public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions, "PAUSE_ACTIVITY_ITEM"); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); }

调用client.handlePauseActivity方法来进行pause activity.这里client就是ActivityThread。里面的方法调用关系:handlePauseActivity()-> performPauseActivity()-> performPauseActivityIfNeeded()

frameworks/base/core/java/android/app/ActivityThread.java
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
    if (r.paused) {//如果已经pause 直接返回
        // You are already paused silly...
        return;
    }
 
    // Always reporting top resumed position loss when pausing an activity. If necessary, it
    // will be restored in performResumeActivity().
    reportTopResumedActivityChanged(r, false /* onTop */, "pausing");
 
    try {
        r.activity.mCalled = false;
        mInstrumentation.callActivityOnPause(r.activity);//这里就是具体调用activity的performPause的地方
        if (!r.activity.mCalled) {
            throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
                    + " did not call through to super.onPause()");
        }
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
        if (!mInstrumentation.onException(r.activity, e)) {
            throw new RuntimeException("Unable to pause activity "
                    + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
        }
    }
    r.setState(ON_PAUSE);//设置activity的状态为pause
}

具体是调用了Instrumentation.callActivityOnPause方法

Instrumentation.java
public void callActivityOnPause(Activity activity) {
    activity.performPause();
}

在pause activity的时候,startPausingLocked会设置超时时间500s:prev.schedulePauseTimeout()。具体调用的是ActivityRecord.java里的schedulePauseTimeout方法

frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
void schedulePauseTimeout() {
    pauseTime = SystemClock.uptimeMillis();
    mAtmService.mH.postDelayed(mPauseTimeoutRunnable, PAUSE_TIMEOUT);
    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
}

会开启一个线程mPauseTimeoutRunnable

frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
private final Runnable mPauseTimeoutRunnable = new Runnable() {
    @Override
    public void run() {
        // We don't at this point know if the activity is fullscreen,
        // so we need to be conservative and assume it isn't.
        Slog.w(TAG, "Activity pause timeout for " + ActivityRecord.this);
        synchronized (mAtmService.mGlobalLock) {
            if (hasProcess()) {
                mAtmService.logAppTooSlow(app, pauseTime, "pausing " + ActivityRecord.this);
            }
            activityPaused(true);
        }
    }
};

activityPaused方法就是用来通知activity已经pause了。

至此,pause activtiy的流程结束。

(2)分析完pause activity,然后是开始继续启动activity。调用ActivityStackSupervisor.java里的startSpecificActivity方法继续启动

frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
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);//根据uid和pid,获取activity对应的进行和线程信息
 
 
    boolean knownToBeDead = false;
    if (wpc != null && wpc.hasThread()) {//如果进程和线程都存在,那么执行下面代码启动activity
        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");//如果进程不存在,那么通过ActivityTaskManagerService创建进程
}

如果进程和线程都存在那么调用realStartActivityLocked去启动activity,否则通过ActivityTaskManagerService的startProcessAsync创建进程,因为是第一次启动,所以是需要ActivityTaskManagerService来创建进程的。(如果是activity之间的跳转,那就不是第一次启动,那么就会直接调用realStartActivityLocked方法启动activity)

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
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.
        final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
                mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
                isTop, hostingType, activity.intent.getComponent());
        mH.sendMessage(m);//向AMS发送新建进程的消息,
    } finally {
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }
}

调用ActivityManagerInternal::startProcess的方法来新建一个线程。ActivityManagerInternal是一个abstract的类。真正的实现类在AMS的内部类LocalService里

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public final class LocalService extends ActivityManagerInternal {
 
......
 
        @Override
        public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
                boolean isTop, String hostingType, ComponentName hostingName) {
            try {
                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
                            + processName);
                }
                synchronized (ActivityManagerService.this) {
                    // If the process is known as top app, set a hint so when the process is
                    // started, the top priority can be applied immediately to avoid cpu being
                    // preempted by other processes before attaching the process of top app.
                    startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                            new HostingRecord(hostingType, hostingName, isTop),
                            ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
                            false /* isolated */, true /* keepIfLarge */);
                }
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
        }
ActivityManagerService.java
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
        boolean isolated, boolean keepIfLarge) {
    return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
            hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
            keepIfLarge, null /* ABI override */, null /* entryPoint */,
            null /* entryPointArgs */, null /* crashHandler */);
}

调用到了ProcessList里的startProcessLocked方法。经过一系列的重载调用,最终调用的是:

frameworks/base/services/core/java/com/android/server/am/ProcessList.java
@GuardedBy("mService")
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) {
    app.pendingStart = true;
    app.killedByAm = false;
    app.removed = false;
    app.killed = false;
    ......
 
    if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
        if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
                "Posting procStart msg for " + app.toShortString());
        mService.mProcStartHandler.post(() -> handleProcessStart(
                app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
                requiredAbi, instructionSet, invokeWith, startSeq));//异步其实最终也是调用的startProcess
        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) {
            Slog.e(ActivityManagerService.TAG, "Failure starting process "
                    + app.processName, e);
            app.pendingStart = false;
            mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                    false, false, true, false, false, app.userId, "start failure");
        }
        return app.pid > 0;
    }
}
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 {
        ......
        } 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});
        }
        checkSlow(startTime, "startProcess: returned from zygote!");
        return startResult;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
}

然后调用了Process里的start方法来新建进程

frameworks/base/core/java/android/os/Process.java
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,
                                       int zygotePolicyFlags,
                                       boolean isTopApp,
                                       @Nullable long[] disabledCompatChanges,
                                       @Nullable Map<String, Pair<String, Long>>
                                               pkgDataInfoMap,
                                       @Nullable Map<String, Pair<String, Long>>
                                               whitelistedDataInfoMap,
                                       boolean bindMountAppsData,
                                       boolean bindMountAppStorageDirs,
                                       @Nullable String[] zygoteArgs) {
    return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, packageName,
                zygotePolicyFlags, isTopApp, disabledCompatChanges,
                pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
                bindMountAppStorageDirs, zygoteArgs);
}

交给ZygoteProcess去start新的进程,在ZygoteProcess里的调用关系start()→startViaZygote()->zygoteSendArgsAndGetResult()->attemptZygoteSendArgsAndGetResult()

frameworks/base/core/java/android/os/ZygoteProcess.java
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
        ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
    try {
        //可以看到这里直接就用zygoteState进行数据读写通信了,而zygotestate其实就是对LocalSocket的封装,这样zygote进程就会在循环中收到信息,开始创建新的进程
        //具体见//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
 
        final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
        final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
 
        zygoteWriter.write(msgStr);
        zygoteWriter.flush();
 
        // Always read the entire result from the input stream to avoid leaving
        // bytes in the stream for future process starts to accidentally stumble
        // upon.
        //最后返回子进程启动的封装信息类
        Process.ProcessStartResult result = new Process.ProcessStartResult();
        result.pid = zygoteInputStream.readInt();
        result.usingWrapper = zygoteInputStream.readBoolean();
 
        if (result.pid < 0) {
            throw new ZygoteStartFailedEx("fork() failed");
        }
 
        return result;
    } catch (IOException ex) {
        zygoteState.close();//关闭socket
        Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
                + ex.toString());
        throw new ZygoteStartFailedEx(ex);
    }
}

至此AMS向Zygote申请新建一个进程的流程就结束了。Zygote会通过AMS传入的信息来fork一个新的App进程。AMS和Zygote之间是通过socket来进行的。

pause launcher和start进程流程已经结束了,接下来就是启动activity。上面提到过,如果进程和线程都存在,调用realStartActivityLocked启动activity,如果不存在,过ActivityTaskManagerService创建进程。现在已经创建了app进程,所以调用realStartActivityLocked方法来启动activity

frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
 
    .....
            // Create activity launch transaction.
            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.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.
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);

执行scheduleTransaction方法,传入ClientLifecycleManager的是LaunchActivityItem。上面也提到过,最终调用的是 ActivityThread 的相关函数实现对 Activity 生命周期函数的调用

frameworks/base/core/java/android/app/ActivityThread.java
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}

调用的是ClientTransactionHandler.java里的方法

frameworks/base/core/java/android/app/ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

在这个方法里发送一个EXECUTE_TRANSACTION的message,是调用了ActivityThread也就是主线程的Handler去发送消息。消息处理的地方调用了TransactionExecutor.java里的execute方法,然后是executeCallbacks方法,在这个方法里会遍历它的execute方法,在上面添加的是LaunchActivityItem。所以会调用到LaunchActivityItem的execute方法

frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
            mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
            mPendingResults, mPendingNewIntents, mIsForward,
            mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

调用了ActivityThread的handleLaunchActivity方法

ActivityThread.java
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    .....
    final Activity a = performLaunchActivity(r, customIntent);
 
    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        if (!r.activity.mFinished && pendingActions != null) {
            pendingActions.setOldState(r.state);
            pendingActions.setRestoreInstanceState(true);
            pendingActions.setCallOnPostCreate(true);
        }
    } else {
        // If there was an error, for any reason, tell the activity manager to stop us.
        try {
            ActivityTaskManager.getService()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
 
    return a;
}

调用了performLaunchActivity方法。这个方法是activity启动的核心方法

ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {//如果package信息为空,重新获取
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }
 
    ComponentName component = r.intent.getComponent();
    if (component == null) {//设置component信息
        component = r.intent.resolveActivity(
            mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    }
 
    if (r.activityInfo.targetActivity != null) {
        component = new ComponentName(r.activityInfo.packageName,
                r.activityInfo.targetActivity);
    }
 
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);//重点:创建activity
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to instantiate activity " + component
                + ": " + e.toString(), e);
        }
    }
 
    try {
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);//获取Application实例
 
        if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
        if (localLOGV) Slog.v(
                TAG, r + ": app=" + app
                + ", appName=" + app.getPackageName()
                + ", pkg=" + r.packageInfo.getPackageName()
                + ", comp=" + r.intent.getComponent().toShortString()
                + ", dir=" + r.packageInfo.getAppDir());
 
        if (activity != null) {
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            if (r.overrideConfig != null) {
                config.updateFrom(r.overrideConfig);
            }
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                    + r.activityInfo.name + " with config " + config);
            //创建窗口实例,并调用activity的attch方法,attach该窗口   
            Window window = null;
            if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                window = r.mPendingRemoveWindow;
                r.mPendingRemoveWindow = null;
                r.mPendingRemoveWindowManager = null;
            }
 
            // Activity resources must be initialized with the same loaders as the
            // application context.
            appContext.getResources().addLoaders(
                    app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
 
            appContext.setOuterContext(activity);
            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);
 
            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的主题
            }
 
            activity.mCalled = false;
            //调用该Activity的onCreate方法
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            if (!activity.mCalled) {
                throw new SuperNotCalledException(
                    "Activity " + r.intent.getComponent().toShortString() +
                    " did not call through to super.onCreate()");
            }
            r.activity = activity;
            mLastReportedWindowingMode.put(activity.getActivityToken(),
                    config.windowConfiguration.getWindowingMode());
        }
        r.setState(ON_CREATE);//设置activity状态为create
 
        // updatePendingActivityConfiguration() reads from mActivities to update
        // ActivityClientRecord which runs in a different thread. Protect modifications to
        // mActivities to avoid race.
        synchronized (mResourcesManager) {
            mActivities.put(r.token, r);
        }
 
    } catch (SuperNotCalledException e) {
        throw e;
 
    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to start activity " + component
                + ": " + e.toString(), e);
        }
    }
 
    return activity;
}
4.Application创建的过程

与在App内部启动一个Activity的不同之处在于,点击桌面Launcher首次启动一个应用程序的时候,会先去创建一个该应用程序对应的进程,然后执行ActivityThread的main()方法去创建该应用对应的Application,然后再去启动首页Activity。上面已经分析了进程的创建和启动首页activtiy,创建该应用对应的Application单独分析

上面分析通过Process里的start创建新的进程,AMS通过Zygote创建应用进程,应用进程启动完成后通知AMS,AMS再通知应用创建Application对象。

ActivityThread类的main()函数是应用的入口函数

ActivtiyThread.java
public static void main(String[] args) {
    ......
    Looper.prepareMainLooper();//创建一个主线程的looper
 
    ......
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);//创建application
 
    ......
    Looper.loop();
 
    throw new RuntimeException("Main thread loop unexpectedly exited");
}
ActivtiyThread.java
@UnsupportedAppUsage
private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {//app进程
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                UserHandle.myUserId());
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        final IActivityManager mgr = ActivityManager.getService();//获取到的是AMS实例
        try {
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        ......
    } else {//system进程

该方法的参数的类型是ActivityThread中的ApplicationThread,ApplicationThread对象充当了Binder的作用,ActivityManagerService会通过attachApplication()传递过来的ApplicationThread对象,与app进行跨进程通信。经过 Binder 调用,进入 system_server 进程,执行 attachApplication

调用AMS里的attachApplication方法→attachApplicationLocked()

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
         int pid, int callingUid, long startSeq) {
 
     ......
         } else if (instr2 != null) {
             thread.bindApplication(processName, appInfo, providerList,
                     instr2.mClass,
                     profilerInfo, instr2.mArguments,
                     instr2.mWatcher,
                     instr2.mUiAutomationConnection, testMode,
                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
                     isRestrictedBackupMode || !normalMode, app.isPersistent(),
                     new Configuration(app.getWindowProcessController().getConfiguration()),
                     app.compat, getCommonServicesLocked(app.isolated),
                     mCoreSettingsObserver.getCoreSettingsLocked(),
                     buildSerial, autofillOptions, contentCaptureOptions,
                     app.mDisabledCompatChanges);  // 绑定App进程
         } else {
             thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
                     null, null, null, testMode,
                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
                     isRestrictedBackupMode || !normalMode, app.isPersistent(),
                     new Configuration(app.getWindowProcessController().getConfiguration()),
                     app.compat, getCommonServicesLocked(app.isolated),
                     mCoreSettingsObserver.getCoreSettingsLocked(),
                     buildSerial, autofillOptions, contentCaptureOptions,
                     app.mDisabledCompatChanges);
         }
          
         // Make app active after binding application or client may be running requests (e.g
         // starting activities) before it is ready.
         app.makeActive(thread, mProcessStats);
         checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
         mProcessList.updateLruProcessLocked(app, false, null);
         checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
         app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
         ......
 }

在attachApplicationLocked()方法中,会调用thread对象的bindApplication()方法,thread对象就是我们传递过来的ApplicationThread对象。

frameworks/base/core/java/android/app/ActivityThread.java
@Override
public final void bindApplication(String processName, ApplicationInfo appInfo,
        ProviderInfoList providerList, ComponentName instrumentationName,
        ProfilerInfo profilerInfo, Bundle instrumentationArgs,
        IInstrumentationWatcher instrumentationWatcher,
        IUiAutomationConnection instrumentationUiConnection, int debugMode,
        boolean enableBinderTracking, boolean trackAllocation,
        boolean isRestrictedBackupMode, boolean persistent, Configuration config,
        CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
        String buildSerial, AutofillOptions autofillOptions,
        ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {
    if (services != null) {
        if (false) {
            // Test code to make sure the app could see the passed-in services.
            for (Object oname : services.keySet()) {
                if (services.get(oname) == null) {
                    continue; // AM just passed in a null service.
                }
                String name = (String) oname;
 
                // See b/79378449 about the following exemption.
                switch (name) {
                    case "package":
                    case Context.WINDOW_SERVICE:
                        continue;
                }
 
                if (ServiceManager.getService(name) == null) {
                    Log.wtf(TAG, "Service " + name + " should be accessible by this app");
                }
            }
        }
 
        // Setup the service cache in the ServiceManager
        ServiceManager.initServiceCache(services);
    }
 
    setCoreSettings(coreSettings);
 
    AppBindData data = new AppBindData();// 封装App进程绑定数据:AppBindData
    data.processName = processName;
    data.appInfo = appInfo;
    data.providers = providerList.getList();
    data.instrumentationName = instrumentationName;
    data.instrumentationArgs = instrumentationArgs;
    data.instrumentationWatcher = instrumentationWatcher;
    data.instrumentationUiAutomationConnection = instrumentationUiConnection;
    data.debugMode = debugMode;
    data.enableBinderTracking = enableBinderTracking;
    data.trackAllocation = trackAllocation;
    data.restrictedBackupMode = isRestrictedBackupMode;
    data.persistent = persistent;
    data.config = config;
    data.compatInfo = compatInfo;
    data.initProfilerInfo = profilerInfo;
    data.buildSerial = buildSerial;
    data.autofillOptions = autofillOptions;
    data.contentCaptureOptions = contentCaptureOptions;
    data.disabledCompatChanges = disabledCompatChanges;
    sendMessage(H.BIND_APPLICATION, data);
}

bindApplication()的方法构造了一个AppBindData对象,AppBindData()封装了和Application交互时的一些信息,然后作为参数,通过sendMessage()方法发送了一个BIND_APPLICATION消息,下面看一下处理这个消息的地方

frameworks/base/core/java/android/app/ActivityThread.java
case BIND_APPLICATION:
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
        AppBindData data = (AppBindData)msg.obj;
        handleBindApplication(data);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        break;

调用了handleBindApplication方法来处理

frameworks/base/core/java/android/app/ActivityThread.java
@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {
    // Register the UI Thread as a sensitive thread to the runtime.
    VMRuntime.registerSensitiveThread();// 将UI线程注册为运行时的虚拟机
    ......
    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);//获取LoadedApk对象
 
    ......
    // 从AppBindData中取出InstrumentationInfo信息
    final InstrumentationInfo ii;
    if (data.instrumentationName != null) {
        try {
            ii = new ApplicationPackageManager(
                    null, getPackageManager(), getPermissionManager())
                    .getInstrumentationInfo(data.instrumentationName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(
                    "Unable to find instrumentation info for: " + data.instrumentationName);
        }
 
        // Warn of potential ABI mismatches.
        if (!Objects.equals(data.appInfo.primaryCpuAbi, ii.primaryCpuAbi)
                || !Objects.equals(data.appInfo.secondaryCpuAbi, ii.secondaryCpuAbi)) {
            Slog.w(TAG, "Package uses different ABI(s) than its instrumentation: "
                    + "package[" + data.appInfo.packageName + "]: "
                    + data.appInfo.primaryCpuAbi + ", " + data.appInfo.secondaryCpuAbi
                    + " instrumentation[" + ii.packageName + "]: "
                    + ii.primaryCpuAbi + ", " + ii.secondaryCpuAbi);
        }
 
        mInstrumentationPackageName = ii.packageName;
        mInstrumentationAppDir = ii.sourceDir;
        mInstrumentationSplitAppDirs = ii.splitSourceDirs;
        mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
        mInstrumentedAppDir = data.info.getAppDir();
        mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
        mInstrumentedLibDir = data.info.getLibDir();
    } else {
        ii = null;
    }
 
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);// 创建Context
    updateLocaleListFromAppContext(appContext,
            mResourcesManager.getConfiguration().getLocales());
 
    ......
 
    // Continue loading instrumentation.
    if (ii != null) {// InstrumentationInfo对象非空
        ApplicationInfo instrApp;
        try {
            instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0,
                    UserHandle.myUserId());// 从InstrumentationInfo中取出各参数, 基于此创建和初始化Instrumentation
        } catch (RemoteException e) {
            instrApp = null;
        }
        if (instrApp == null) {
            instrApp = new ApplicationInfo();
        }
        ii.copyTo(instrApp);// 将InstrumentationInfo里的参数拷贝到ApplicationInfo对象
        instrApp.initForUser(UserHandle.myUserId());
        final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                appContext.getClassLoader(), false, true, false);
 
        // The test context's op package name == the target app's op package name, because
        // the app ops manager checks the op package name against the real calling UID,
        // which is what the target package name is associated with.
        final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
                appContext.getOpPackageName());
 
        try {
            final ClassLoader cl = instrContext.getClassLoader();
            mInstrumentation = (Instrumentation)
                cl.loadClass(data.instrumentationName.getClassName()).newInstance();
        } catch (Exception e) {
            throw new RuntimeException(
                "Unable to instantiate instrumentation "
                + data.instrumentationName + ": " + e.toString(), e);
        }
 
        final ComponentName component = new ComponentName(ii.packageName, ii.name);
        mInstrumentation.init(this, instrContext, appContext, component,
                data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
 
        if (mProfiler.profileFile != null && !ii.handleProfiling
                && mProfiler.profileFd == null) {
            mProfiler.handlingProfiling = true;
            final File file = new File(mProfiler.profileFile);
            file.getParentFile().mkdirs();
            Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
        }
    } else {
        mInstrumentation = new Instrumentation();
        mInstrumentation.basicInit(this);// 初始化Instrumentation
    }
 
    ......
    Application app;
    final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
    final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
    try {
        // If the app is being launched for full backup or restore, bring it up in
        // a restricted environment with the base application class.
        app = data.info.makeApplication(data.restrictedBackupMode, null);//创建Application对象并调用其attach()方法
 
        // Propagate autofill compat state
        app.setAutofillOptions(data.autofillOptions);
 
        // Propagate Content Capture options
        app.setContentCaptureOptions(data.contentCaptureOptions);
 
        mInitialApplication = app;
 
        // don't bring up providers in restricted mode; they may depend on the
        // app's custom Application class
        if (!data.restrictedBackupMode) {
            if (!ArrayUtils.isEmpty(data.providers)) {
                installContentProviders(app, data.providers);
            }
        }
 
        // Do this after providers, since instrumentation tests generally start their
        // test thread at this point, and we don't want that racing.
        try {
            mInstrumentation.onCreate(data.instrumentationArgs);回调Application的onCreate(),内部是空实现
        }
        catch (Exception e) {
            throw new RuntimeException(
                "Exception thrown in onCreate() of "
                + data.instrumentationName + ": " + e.toString(), e);
        }
        try {
            mInstrumentation.callApplicationOnCreate(app);//通过mInstrumentation对象,回调Application的onCreate()方法 
        } catch (Exception e) {
            if (!mInstrumentation.onException(app, e)) {
                throw new RuntimeException(
                  "Unable to create application " + app.getClass().getName()
                  + ": " + e.toString(), e);
            }
        }
    } finally {
        // If the app targets < O-MR1, or doesn't change the thread policy
        // during startup, clobber the policy to maintain behavior of b/36951662
        if (data.appInfo.targetSdkVersion < Build.VERSION_CODES.O_MR1
                || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {
            StrictMode.setThreadPolicy(savedPolicy);
        }
    }
 
    // Preload fonts resources
    //预加载字体资源
    FontsContract.setApplicationContextForResources(appContext);
    if (!Process.isIsolated()) {
        try {
            final ApplicationInfo info =
                    getPackageManager().getApplicationInfo(
                            data.appInfo.packageName,
                            PackageManager.GET_META_DATA /*flags*/,
                            UserHandle.myUserId());
            if (info.metaData != null) {
                final int preloadedFontsResource = info.metaData.getInt(
                        ApplicationInfo.METADATA_PRELOADED_FONTS, 0);
                if (preloadedFontsResource != 0) {
                    data.info.getResources().preloadFonts(preloadedFontsResource);
                }
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}

在 handleBindApplication() 的过程中,会创建 Application 并调用其 onCreate 方法。使用makeApplication方法来创建Application

frameworks/base/core/java/android/app/LoadedApk.java
public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    if (mApplication != null) {//避免Application重复创建
        return mApplication;
    }
 
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
 
    Application app = null;
 
    String appClass = mApplicationInfo.className;//获取Application的类名
    if (forceDefaultAppClass || (appClass == null)) {//如果没有获取到Application类名,默认类名为Application.java
        appClass = "android.app.Application";
    }
 
    try {
        ......
 
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        // The network security config needs to be aware of multiple
        // applications in the same process to handle discrepancies
        NetworkSecurityConfigProvider.handleNewApplication(appContext);//配置网络安全相关
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);//创建Application
        appContext.setOuterContext(app);
    } catch (Exception e) {
        ......
    }
    mActivityThread.mAllApplications.add(app);
    mApplication = app;
 
    if (instrumentation != null) {
        try {
            instrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
            if (!instrumentation.onException(app, e)) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to create application " + app.getClass().getName()
                    + ": " + e.toString(), e);
            }
        }
    }
 
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
    return app;
}

可以看出,调用了instrumentation.newApplication方法来创建Application

frameworks/base/core/java/android/app/Instrumentation.java
public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);
    app.attach(context);
    return app;
}

在Application创建完成后,会调用attach(context)函数。

以上,就是Application的创建过程。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值