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生命周期。

相关推荐
拭心2 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
带电的小王4 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
梦想平凡5 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
元争栈道5 小时前
webview和H5来实现的android短视频(短剧)音视频播放依赖控件
android·音视频
阿甘知识库6 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
元争栈道6 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源
android·音视频
MuYe7 小时前
Android Hook - 动态加载so库
android
居居飒7 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
Henry_He10 小时前
桌面列表小部件不能点击的问题分析
android
工程师老罗10 小时前
Android笔试面试题AI答之Android基础(1)
android