Android11 应用启动流程

应用层调用startActivity,会跨进程调用导致ATMS的startActivityAsUser方法被调用

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
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对象,先通过各个set方法,将数据保存到其mRequest成员中,最后调用execute方法

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
	//省略
	res = executeRequest(mRequest);
	//省略
}

executeRequest

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int executeRequest(Request request) {
	//省略
	final IApplicationThread caller = request.caller;
	Intent intent = request.intent;
	//...从request中取出之前通过set保存的值
	//省略
	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);
	//省略
	mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity, intentGrants);

}

主要是创建ActivityRecord 并调用startActivityUnchecked方法

startActivityUnchecked

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
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;
    }

startActivityInner

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    //省略,主要是一些参数的计算,比如启动模式之类
	if (mTargetStack == null) {
    	mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, targetTask, mOptions);//创建Task并挂载到层级结构树
    }
	if (newTask) {
            final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                    ? mSourceRecord.getTask() : null;
            setNewTask(taskToAffiliate);//将ActivityRecord挂载到上面的Task下
            //省略
        } else if (mAddingToTask) {
            addOrReparentStartingActivity(targetTask, "adding to task");
  	}
	
	//省略
	 mTargetStack.startActivityLocked(mStartActivity,
                topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask,
                mKeepCurTransition, mOptions);//启动窗口

	//省略
	if (mDoResume) {
		mRootWindowContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);//继续处理
	}
}

startActivityInner主要完成

  1. 层级结构树节点的创建并挂载
  2. 启动窗口相关
  3. 调用RootWindowContainer的resumeFocusedStacksTopActivities继续处理

resumeFocusedStacksTopActivities

c 复制代码
 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);
        }

	//省略

ActivityStack的resumeTopActivityUncheckedLocked方法直接调用resumeTopActivityInnerLocked

ActivityStack.resumeTopActivityInnerLocked

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options){
	//省略
	ActivityRecord next = topRunningActivity(true /* focusableOnly */);//得到需要打开的Activity
	
	//省略
	boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next);//调用startPausingLocked去暂停上一个应用

	//省略
	 if (pausing) {
            if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
                    "resumeTopActivityLocked: Skip resume: need to start pausing");
            // At this point we want to put the upcoming activity's process
            // at the top of the LRU list, since we know we will be needing it
            // very soon and it would be a waste to let it get killed if it
            // happens to be sitting towards the end.
            if (next.attachedToProcess()) {
                next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
                        true /* activityChange */, false /* updateOomAdj */,
                        false /* addPendingTopUid */);
            } else if (!next.isProcessRunning()) {
                // Since the start-process is asynchronous, if we already know the process of next
                // activity isn't running, we can start the process earlier to save the time to wait
                // for the current activity to be paused.
                final boolean isTop = this == taskDisplayArea.getFocusedStack();
                mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
                        isTop ? "pre-top-activity" : "pre-activity");//开启新进程
            }
	
	//省略
}

resumeTopActivityInnerLocked 首先是要去暂停上一个应用,比如在Launcher上点击图标启动应用,需要暂停Launcher,然后为要启动的应用新建线程。

startPausingLocked

pauseBackStacks会调用到startPausingLocked去暂停应用

startPausingLocked

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming) {
		//省略
		if (prev.attachedToProcess()) {
            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));
            } 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;
        }
	//省略
}

Android 11 在AMS和Activity之间的跨进程通讯有变动,现在是采取事物的方式,scheduleTransaction用于传递事务,注意第三个参数,最终导致PauseActivityItem的execute方法被执行

c 复制代码
//frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
@Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
        android.util.Log.d("test","PauseActivityItem:",new Exception());
        client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
                "PAUSE_ACTIVITY_ITEM");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

最终Activity的 去执行onPause这个生命周期。

PauseActivityItem的execute执行完之后,会继续执行其postExecute方法

c 复制代码
//frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
@Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        if (mDontReport) {
            return;
        }
        try {
            // TODO(lifecycler): Use interface callback instead of AMS.
            ActivityTaskManager.getService().activityPaused(token);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

ATMS.activityPaused

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
 @Override
    public final void activityPaused(IBinder token) {
        final long origId = Binder.clearCallingIdentity();
        synchronized (mGlobalLock) {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused");
            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
            if (r != null) {
                r.activityPaused(false);
            }
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
        Binder.restoreCallingIdentity(origId);
    }

ActivityRecord.activityPaused

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
void activityPaused(boolean timeout) {
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
                "Activity paused: token=" + appToken + ", timeout=" + timeout);

        final ActivityStack stack = getStack();

        if (stack != null) {
            removePauseTimeout();

            if (stack.mPausingActivity == this) {
                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + this
                        + (timeout ? " (due to timeout)" : " (pause complete)"));
                mAtmService.deferWindowLayout();
                try {
                    stack.completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
                } finally {
                    mAtmService.continueWindowLayout();
                }
                return;
            } else {
               //省略
      
    }

ActivityStack.completePauseLocked

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
	//省略
	if (resumeNext) {
            final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
            if (topStack != null && !topStack.shouldSleepOrShutDownActivities()) {
                mRootWindowContainer.resumeFocusedStacksTopActivities(topStack, prev, null);
            } else {
                checkReadyForSleep();
                final ActivityRecord top = topStack != null ? topStack.topRunningActivity() : null;
                if (top == null || (prev != null && top != prev)) {
                    // If there are no more activities available to run, do resume anyway to start
                    // something. Also if the top activity on the stack is not the just paused
                    // activity, we need to go ahead and resume it to ensure we complete an
                    // in-flight app switch.
                    mRootWindowContainer.resumeFocusedStacksTopActivities();
                }
            }
        }
	
	//省略
}

可以看出,上一个应用暂停完成之后,又调用到RootWindowContainer的resumeFocusedStacksTopActivities方法。这是因为在启动新进程那条调用链上,如果上一个应用还没暂停,就不会继续往下执行,所以应用暂停完成之后,需要再次调用确保真正启动应用的地方会继续往下执行。

startProcessAsync

关于进程的创建,在Android11 FallbackHome启动和关闭流程分析 一文中,已经分析过,子进程fork之后,ActivityThread的main方法

c 复制代码
//frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
        //省略
        Looper.prepareMainLooper();

       	//省略
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        //省略
        Looper.loop();

        throw new RuntimeException("Main thread loop 

在attach方法中,调用AMS的attachApplication方法

AMS.attachApplication

c 复制代码
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        if (thread == null) {
            throw new SecurityException("Invalid application interface");
        }
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }

attachApplicationLocked

c 复制代码
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
	//省略
	 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);//执行Application的onCreate方法

	//省略
	if (normalMode) {
            try {
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
    }
    //省略
}

ActivityTaskManagerService$LocalService.attachApplication

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
                }
                try {
                    return mRootWindowContainer.attachApplication(wpc);
                } finally {
                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                }
            }
        }

RootWindowContainer.attachApplication

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean attachApplication(WindowProcessController app) throws RemoteException {
        boolean didSomething = false;
        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
            mTmpRemoteException = null;
            mTmpBoolean = false; // Set to true if an activity was started.

            final DisplayContent display = getChildAt(displayNdx);
            for (int areaNdx = display.getTaskDisplayAreaCount() - 1; areaNdx >= 0; --areaNdx) {
                final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(areaNdx);
                for (int taskNdx = taskDisplayArea.getStackCount() - 1; taskNdx >= 0; --taskNdx) {
                    final ActivityStack rootTask = taskDisplayArea.getStackAt(taskNdx);
                    if (rootTask.getVisibility(null /*starting*/) == STACK_VISIBILITY_INVISIBLE) {
                        break;
                    }
                    final PooledFunction c = PooledLambda.obtainFunction(
                            RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
                            PooledLambda.__(ActivityRecord.class), app,
                            rootTask.topRunningActivity());
                    rootTask.forAllActivities(c);//1
                    c.recycle();
                    if (mTmpRemoteException != null) {
                        throw mTmpRemoteException;
                    }
                }
            }
            didSomething |= mTmpBoolean;
        }
        if (!didSomething) {
            ensureActivitiesVisible(null, 0, false /* preserve_windows */);
        }
        return didSomething;
    }

注释1处,对于满足条件的每个Task,都会去执行startActivityForAttachedApplicationIfNeeded方法

c 复制代码
//frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
            WindowProcessController app, ActivityRecord top) {
       //省略
        try {
            if (mStackSupervisor.realStartActivityLocked(r, app,
                    top == r && r.isFocusable() /*andResume*/, true /*checkConfig*/)) {
                mTmpBoolean = true;
            }
        } catch (RemoteException e) {
         //省略
        }
        return false;
    }
c 复制代码
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
     	//省略
	if (!mRootWindowContainer.allPausedActivitiesComplete()) {//可以看出,这里需要判断上一个应用是否暂停完成,才会向下执行
            // While there are activities pausing we skipping starting any new activities until
            // pauses are complete. NOTE: that we also do this for activities that are starting in
            // the paused state because they will first be resumed then paused on the client side.
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                    "realStartActivityLocked: Skipping start of r=" + r
                    + " some activities pausing...");
            return false;
  	}
	// 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);

		//省略
}

也是采用事物的方式,和应用进程相互通信,最后去执行Activity 的 onCreate,onResume生命周期。

相关推荐
用户2018792831674 小时前
ANR之RenderThread不可中断睡眠state=D
android
煤球王子4 小时前
简单学:Android14中的Bluetooth—PBAP下载
android
小趴菜82274 小时前
安卓接入Max广告源
android
齊家治國平天下4 小时前
Android 14 系统 ANR (Application Not Responding) 深度分析与解决指南
android·anr
ZHANG13HAO4 小时前
Android 13.0 Framework 实现应用通知使用权默认开启的技术指南
android
【ql君】qlexcel4 小时前
Android 安卓RIL介绍
android·安卓·ril
写点啥呢4 小时前
android12解决非CarProperty接口深色模式设置后开机无法保持
android·车机·aosp·深色模式·座舱
IT酷盖4 小时前
Android解决隐藏依赖冲突
android·前端·vue.js
努力学习的小廉6 小时前
初识MYSQL —— 数据库基础
android·数据库·mysql
风起云涌~6 小时前
【Android】浅谈androidx.startup.InitializationProvider
android