android Activity启动过程(四)startActivityUncheckedLocked

2018/07/27 17:23
阅读数 146

 

 

final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
            boolean doResume, Bundle options, TaskRecord inTask) {
        final Intent intent = r.intent;
        final int callingUid = r.launchedFromUid;

        // In some flows in to this function, we retrieve the task record and hold on to it
        // without a lock before calling back in to here...  so the task at this point may
        // not actually be in recents.  Check for that, and if it isn't in recents just
        // consider it invalid.
        if (inTask != null && !inTask.inRecents) {
            Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
            inTask = null;
        }

        final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
        final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
        final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;

        int launchFlags = intent.getFlags();
        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
                (launchSingleInstance || launchSingleTask)) {
            // We have a conflict between the Intent and the Activity manifest, manifest wins.
            Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
                    "\"singleInstance\" or \"singleTask\"");
            launchFlags &=
                    ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
        } else {
            switch (r.info.documentLaunchMode) {
                case ActivityInfo.DOCUMENT_LAUNCH_NONE:
                    break;
                case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
                    break;
                case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
                    break;
                case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
                    launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
                    break;
            }
        }

        final boolean launchTaskBehind = r.mLaunchTaskBehind
                && !launchSingleTask && !launchSingleInstance
                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0;

        if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
            // For whatever reason this activity is being launched into a new
            // task...  yet the caller has requested a result back.  Well, that
            // is pretty messed up, so instead immediately send back a cancel
            // and let the new task continue launched as normal without a
            // dependency on its originator.
            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
            r.resultTo.task.stack.sendActivityResultLocked(-1,
                    r.resultTo, r.resultWho, r.requestCode,
                    Activity.RESULT_CANCELED, null);
            r.resultTo = null;
        }

        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
        }

        // If we are actually going to launch in to a new task, there are some cases where
        // we further want to do multiple task.
        if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
            if (launchTaskBehind
                    || r.info.documentLaunchMode == ActivityInfo.DOCUMENT_LAUNCH_ALWAYS) {
                launchFlags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
            }
        }

        // We'll invoke onUserLeaving before onPause only if the launching
        // activity did not explicitly state that this is an automated launch.
        mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
        if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);

        // If the caller has asked not to resume at this point, we make note
        // of this in the record so that we can skip it when trying to find
        // the top running activity.
        if (!doResume) {
            r.delayedResume = true;
        }
        
        //如果从Launcher程序启动应用,launchFlags为 FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 
        //否则一般情况下launcheFlags为0,除非启动Activity时设置了特殊的flag
         //启动Activity时默认不会设置FLAG_ACTIVITY_PREVIOUS_IS_TOP 
         //故此notTop默认情况下会是null

        ActivityRecord notTop =
                (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;

        // If the onlyIfNeeded flag is set, then we can do this if the activity
        // being launched is the same as the one making the call...  or, as
        // a special case, if we do not know the caller then we count the
        // current top activity as the caller.
        //START_FLAG_ONLY_IF_NEEDED表示只有在需要的时候才启动目标Activity。也就是说如果调用者和被启动的是一个,那么就没有必要去进行重复的步骤了
        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
            //默认情况下这里的代码不会执行
            ActivityRecord checkedCaller = sourceRecord;
            if (checkedCaller == null) {
                checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
            }
            if (!checkedCaller.realActivity.equals(r.realActivity)) {
                // Caller is not the same as launcher, so always needed.
                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
            }
        }

        boolean addingToTask = false;
        TaskRecord reuseTask = null;

        // If the caller is not coming from another activity, but has given us an
        // explicit task into which they would like us to launch the new activity,
        // then let's see about doing that.
        /*
         * 如果调用者不是来自另一个activity(不是在activity中调用startActivity),
         * 但是给了我们用于放入新activity的一个明确的task,将执行下面代码
         *
         * 我们往上追溯,发现inTask是 中 ActivityManagerService.startActivityAsUser()方法传递的null,
         * 所以if里面的不会执行
         */
        if (sourceRecord == null && inTask != null && inTask.stack != null) {
            final Intent baseIntent = inTask.getBaseIntent();
            final ActivityRecord root = inTask.getRootActivity();
            if (baseIntent == null) {
                ActivityOptions.abort(options);
                throw new IllegalArgumentException("Launching into task without base intent: "
                        + inTask);
            }

            // If this task is empty, then we are adding the first activity -- it
            // determines the root, and must be launching as a NEW_TASK.
            if (launchSingleInstance || launchSingleTask) {
                if (!baseIntent.getComponent().equals(r.intent.getComponent())) {
                    ActivityOptions.abort(options);
                    throw new IllegalArgumentException("Trying to launch singleInstance/Task "
                            + r + " into different task " + inTask);
                }
                if (root != null) {
                    ActivityOptions.abort(options);
                    throw new IllegalArgumentException("Caller with inTask " + inTask
                            + " has root " + root + " but target is singleInstance/Task");
                }
            }

            // If task is empty, then adopt the interesting intent launch flags in to the
            // activity being started.
            if (root == null) {
                final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT
                        | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
                launchFlags = (launchFlags&~flagsOfInterest)
                        | (baseIntent.getFlags()&flagsOfInterest);
                intent.setFlags(launchFlags);
                inTask.setIntent(r);
                addingToTask = true;

            // If the task is not empty and the caller is asking to start it as the root
            // of a new task, then we don't actually want to start this on the task.  We
            // will bring the task to the front, and possibly give it a new intent.
            } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
                addingToTask = false;

            } else {
                addingToTask = true;
            }

            reuseTask = inTask;
        } else {
            inTask = null;
        }

       //根据activity的设置,如果满足下列条件,将launchFlags置为FLAG_ACTIVITY_NEW_TASK
        if (inTask == null) {
            if (sourceRecord == null) {
                // This activity is not being started from another...  in this
                // case we -always- start a new task.
                 //如果调用者为null,将launchFlags置为 创建一个新task
                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
                    Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
                            "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
                }
            } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                // The original activity who is starting us is running as a single
                // instance...  this new activity it is starting must go on its
                // own task.
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
            } else if (launchSingleInstance || launchSingleTask) {
                // The activity being started is a single instance...  it always
                // gets launched into its own task.
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
            }
        }

        ActivityInfo newTaskInfo = null;
        Intent newTaskIntent = null;
        ActivityStack sourceStack;
        if (sourceRecord != null) {
            if (sourceRecord.finishing) {
                // If the source is finishing, we can't further count it as our source.  This
                // is because the task it is associated with may now be empty and on its way out,
                // so we don't want to blindly throw it in to that task.  Instead we will take
                // the NEW_TASK flow and try to find a task for it. But save the task information
                // so it can be used when creating the new task.
                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
                    newTaskInfo = sourceRecord.info;
                    newTaskIntent = sourceRecord.task.intent;
                }
                sourceRecord = null;
                sourceStack = null;
            } else {
                sourceStack = sourceRecord.task.stack;
            }
        } else {
            sourceStack = null;
        }

        boolean movedHome = false;
        ActivityStack targetStack;

        intent.setFlags(launchFlags);

        // We may want to try to place the new activity in to an existing task.  We always
        // do this if the target activity is singleTask or singleInstance; we will also do
        // this if NEW_TASK has been requested, and there is not an additional qualifier telling
        // us to still place it in a new task: multi task, always doc mode, or being asked to
        // launch this as a new task behind the current one.
        /*
         * 我们尝试将新的activity放在一个现有的任务中。但是如果activity被要求是singleTask或者singleInstance,
         * 我们会将activity放入一个新的task中.下面的if中主要处理将目标进程置于栈顶,然后将目标activity显示
         */
        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
                || launchSingleInstance || launchSingleTask) {
            // If bring to front is requested, and no result is requested and we have not
            // been given an explicit task to launch in to, and
            // we can find a task that was started with this same
            // component, then instead of launching bring that one to the front.
             //如果被开启的activity不是需要开启新的task,而是single instance或者singleTask,
            if (inTask == null && r.resultTo == null) {
                // See if there is a task to bring to the front.  If this is
                // a SINGLE_INSTANCE activity, there can be one and only one
                // instance of it in the history, and it is always in its own
                // unique task, so we do a special search.
                //检查此activity是否已经开启了SINGLE_INSTANCE
                //findTaskLocked()方法用于查找目标activity所在的task
                ActivityRecord intentActivity = !launchSingleInstance ?
                        findTaskLocked(r) : findActivityLocked(intent, r.info);
                if (intentActivity != null) {
                    if (isLockTaskModeViolation(intentActivity.task)) {
                        showLockTaskToast();
                        Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
                    }
                    if (r.task == null) {
                        r.task = intentActivity.task;
                    }
                    targetStack = intentActivity.task.stack;
                    targetStack.mLastPausedActivity = null;
                    if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
                            + " from " + intentActivity);
                    targetStack.moveToFront();
                    if (intentActivity.task.intent == null) {
                        // This task was started because of movement of
                        // the activity based on affinity...  now that we
                        // are actually launching it, we can assign the
                        // base intent.
                        intentActivity.task.setIntent(r);
                    }
                    // If the target task is not in the front, then we need
                    // to bring it to the front...  except...  well, with
                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
                    // to have the same behavior as if a new instance was
                    // being started, which means not bringing it to the front
                    // if the caller is not itself in the front.
                    //如果目标不在栈顶,我们需要把它放到栈顶
                    final ActivityStack lastStack = getLastStack();
                    ActivityRecord curTop = lastStack == null?
                            null : lastStack.topRunningNonDelayedActivityLocked(notTop);
                    if (curTop != null && (curTop.task != intentActivity.task ||
                            curTop.task != lastStack.topTask())) {
                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
                                sourceStack.topActivity().task == sourceRecord.task)) {
                            // We really do want to push this one into the
                            // user's face, right now.
                            if (launchTaskBehind && sourceRecord != null) {
                                intentActivity.setTaskToAffiliateWith(sourceRecord.task);
                            }
                            movedHome = true;
                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
                            if ((launchFlags &
                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
                                // Caller wants to appear on home activity.
                                intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
                            }
                            options = null;
                        }
                    }
                    // If the caller has requested that the target task be
                    // reset, then do so.
                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
                    }
                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
                        // We don't need to start a new activity, and
                        // the client said not to do anything if that
                        // is the case, so this is it!  And for paranoia, make
                        // sure we have correctly resumed the top activity.
                        if (doResume) {
                            resumeTopActivitiesLocked(targetStack, null, options);
                        } else {
                            ActivityOptions.abort(options);
                        }
                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                    }
                    if ((launchFlags &
                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
                        // The caller has requested to completely replace any
                        // existing task with its new activity.  Well that should
                        // not be too hard...
                        reuseTask = intentActivity.task;
                        reuseTask.performClearTaskLocked();
                        reuseTask.setIntent(r);
                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
                            || launchSingleInstance || launchSingleTask) {
                        //将task中位于目标activity上面的其他activitys清理掉
                        // In this situation we want to remove all activities
                        // from the task up to the one being started.  In most
                        // cases this means we are resetting the task to its
                        // initial state.
                        ActivityRecord top =
                                intentActivity.task.performClearTaskLocked(r, launchFlags);
                        if (top != null) {
                            if (top.frontOfTask) {
                                // Activity aliases may mean we use different
                                // intents for the top activity, so make sure
                                // the task now has the identity of the new
                                // intent.
                                top.task.setIntent(r);
                            }
                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
                                    r, top.task);
                            top.deliverNewIntentLocked(callingUid, r.intent);
                        } else {
                            // A special case: we need to
                            // start the activity because it is not currently
                            // running, and the caller has asked to clear the
                            // current task to have this activity at the top.
                            addingToTask = true;
                            // Now pretend like this activity is being started
                            // by the top of its task, so it is put in the
                            // right place.
                            sourceRecord = intentActivity;
                        }
                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
                        // In this case the top activity on the task is the
                        // same as the one being launched, so we take that
                        // as a request to bring the task to the foreground.
                        // If the top activity in the task is the root
                        // activity, deliver this new intent to it if it
                        // desires.
                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop)
                                && intentActivity.realActivity.equals(r.realActivity)) {
                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
                                    intentActivity.task);
                            if (intentActivity.frontOfTask) {
                                intentActivity.task.setIntent(r);
                            }
                            intentActivity.deliverNewIntentLocked(callingUid, r.intent);
                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
                            // In this case we are launching the root activity
                            // of the task, but with a different intent.  We
                            // should start a new instance on top.
                            addingToTask = true;
                            sourceRecord = intentActivity;
                        }
                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
                        // In this case an activity is being launched in to an
                        // existing task, without resetting that task.  This
                        // is typically the situation of launching an activity
                        // from a notification or shortcut.  We want to place
                        // the new activity on top of the current task.
                        addingToTask = true;
                        sourceRecord = intentActivity;
                    } else if (!intentActivity.task.rootWasReset) {
                        // In this case we are launching in to an existing task
                        // that has not yet been started from its front door.
                        // The current task has been brought to the front.
                        // Ideally, we'd probably like to place this new task
                        // at the bottom of its stack, but that's a little hard
                        // to do with the current organization of the code so
                        // for now we'll just drop it.
                        intentActivity.task.setIntent(r);
                    }
                    if (!addingToTask && reuseTask == null) {
                        // We didn't do anything...  but it was needed (a.k.a., client
                        // don't use that intent!)  And for paranoia, make
                        // sure we have correctly resumed the top activity.
                        if (doResume) {
                            targetStack.resumeTopActivityLocked(null, options);
                        } else {
                            ActivityOptions.abort(options);
                        }
                        return ActivityManager.START_TASK_TO_FRONT;
                    }
                }
            }
        }

        //String uri = r.intent.toURI();
        //Intent intent2 = new Intent(uri);
        //Slog.i(TAG, "Given intent: " + r.intent);
        //Slog.i(TAG, "URI is: " + uri);
        //Slog.i(TAG, "To intent: " + intent2);

        if (r.packageName != null) {
            // If the activity being launched is the same as the one currently
            // at the top, then we need to check if it should only be launched
            // once.
            //如果被启动的Activity正好是栈顶的Activity,
            //并且被启动的Activity启动模式是singleTop或者singleTask,
            //则不用将新的ActivityRecord加入到栈里
            //top Activity为Launcher应用的Activity
            ActivityStack topStack = getFocusedStack();
            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
            //当前处于堆栈顶端的task
            if (top != null && r.resultTo == null) {
                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                    if (top.app != null && top.app.thread != null) {
                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
                            || launchSingleTop || launchSingleTask) {
                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
                                    top.task);
                            // For paranoia, make sure we have correctly
                            // resumed the top activity.
                            topStack.mLastPausedActivity = null;
                            if (doResume) {
                                resumeTopActivitiesLocked();
                            }
                            ActivityOptions.abort(options);
                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
                                // We don't need to start a new activity, and
                                // the client said not to do anything if that
                                // is the case, so this is it!
                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                            }
                            top.deliverNewIntentLocked(callingUid, r.intent);
                            return ActivityManager.START_DELIVERED_TO_TOP;
                        }
                    }
                }
            }

        } else {
            if (r.resultTo != null) {
                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
                        r.requestCode, Activity.RESULT_CANCELED, null);
            }
            ActivityOptions.abort(options);
            //包名为空,直接返回,没有找到
            return ActivityManager.START_CLASS_NOT_FOUND;
        }

        boolean newTask = false;
        boolean keepCurTransition = false;

        TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
                sourceRecord.task : null;

        // Should this be considered a new task?
        if (r.resultTo == null && inTask == null && !addingToTask
                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
            if (isLockTaskModeViolation(reuseTask)) {
                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
            newTask = true;
            targetStack = adjustStackFocus(r, newTask);
            if (!launchTaskBehind) {
                targetStack.moveToFront();
            }
            if (reuseTask == null) {
                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
                        newTaskInfo != null ? newTaskInfo : r.info,
                        newTaskIntent != null ? newTaskIntent : intent,
                        voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
                        taskToAffiliate);
                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
                        r.task);
            } else {
                r.setTask(reuseTask, taskToAffiliate);
            }
            if (!movedHome) {
                if ((launchFlags &
                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
                    // Caller wants to appear on home activity, so before starting
                    // their own activity we will bring home to the front.
                    r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
                }
            }
        } else if (sourceRecord != null) {
            final TaskRecord sourceTask = sourceRecord.task;
            if (isLockTaskModeViolation(sourceTask)) {
                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
            targetStack = sourceTask.stack;
            targetStack.moveToFront();
            final TaskRecord topTask = targetStack.topTask();
            if (topTask != sourceTask) {
                targetStack.moveTaskToFrontLocked(sourceTask, r, options);
            } else {
                mWindowManager.moveTaskToTop(topTask.taskId);
            }
            if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
                // In this case, we are adding the activity to an existing
                // task, but the caller has asked to clear that task if the
                // activity is already running.
                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
                keepCurTransition = true;
                if (top != null) {
                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
                    top.deliverNewIntentLocked(callingUid, r.intent);
                    // For paranoia, make sure we have correctly
                    // resumed the top activity.
                    targetStack.mLastPausedActivity = null;
                    if (doResume) {
                        targetStack.resumeTopActivityLocked(null);
                    }
                    ActivityOptions.abort(options);
                    return ActivityManager.START_DELIVERED_TO_TOP;
                }
            } else if (!addingToTask &&
                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
                // In this case, we are launching an activity in our own task
                // that may already be running somewhere in the history, and
                // we want to shuffle it to the front of the stack if so.
                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
                if (top != null) {
                    final TaskRecord task = top.task;
                    task.moveActivityToFrontLocked(top);
                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
                    top.updateOptionsLocked(options);
                    top.deliverNewIntentLocked(callingUid, r.intent);
                    targetStack.mLastPausedActivity = null;
                    if (doResume) {
                        targetStack.resumeTopActivityLocked(null);
                    }
                    return ActivityManager.START_DELIVERED_TO_TOP;
                }
            }
            // An existing activity is starting this new activity, so we want
            // to keep the new one in the same task as the one that is starting
            // it.
            r.setTask(sourceTask, null);
            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
                    + " in existing task " + r.task + " from source " + sourceRecord);

        } else if (inTask != null) {
            // The calling is asking that the new activity be started in an explicit
            // task it has provided to us.
            //在调用者指定的确定的task中开启目标activity
            if (isLockTaskModeViolation(inTask)) {
                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
            targetStack = inTask.stack;
            targetStack.moveTaskToFrontLocked(inTask, r, options);
            targetStack.moveToFront();
            mWindowManager.moveTaskToTop(inTask.taskId);

            // Check whether we should actually launch the new activity in to the task,
            // or just reuse the current activity on top.
            ActivityRecord top = inTask.getTopActivity();
            if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
                        || launchSingleTop || launchSingleTask) {
                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
                        // We don't need to start a new activity, and
                        // the client said not to do anything if that
                        // is the case, so this is it!
                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                    }
                    top.deliverNewIntentLocked(callingUid, r.intent);
                    return ActivityManager.START_DELIVERED_TO_TOP;
                }
            }

            if (!addingToTask) {
                // We don't actually want to have this activity added to the task, so just
                // stop here but still tell the caller that we consumed the intent.
                ActivityOptions.abort(options);
                return ActivityManager.START_TASK_TO_FRONT;
            }

            r.setTask(inTask, null);
            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
                    + " in explicit task " + r.task);

        } else {
            // This not being started from an existing activity, and not part
            // of a new task...  just put it in the top task, though these days
            // this case should never happen.
            targetStack = adjustStackFocus(r, newTask);
            targetStack.moveToFront();
            ActivityRecord prev = targetStack.topActivity();
            r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
                            r.info, intent, null, null, true), null);
            mWindowManager.moveTaskToTop(r.task.taskId);
            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
                    + " in new guessed " + r.task);
        }

        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
                intent, r.getUriPermissionsLocked(), r.userId);

        if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
            r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
        }
        if (newTask) {
            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
        }
        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
        targetStack.mLastPausedActivity = null;
        //继续调用目标ActivityStack的startActivityLocked()方法,这个方法没有返回值,执行完毕之后直接返回START_SUCCESS
        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
        if (!launchTaskBehind) {
            // Don't set focus on an activity that's going to the back.
            mService.setFocusedActivityLocked(r);
        }
        return ActivityManager.START_SUCCESS;
    }
实际场景分析

实际场景1:

应用内有两个Activity,A和B,A为第应用入口Activity,从A可跳转至B,A和B的启动模式都为standard

1)从Launcher程序第1次启动应用时的任务调度情况:

任务调度时会创建新task并将新的ActivityRecord加入这个新的task

2)然后跳转至应用内Activity时的任务调度情况:

任务调度时会将新的ActivityRecord加入已有的task

3)然后按Home键,再打开应用程序时的调度情况:

任务调度时会先找到已有的相关task,并显示栈顶的Activity

1)从Launcher程序第1次启动应用时

会创建新task并将新的ActivityRecord加入这个新的task,任务调度执行如下所示:

final int startActivityUncheckedLocked(ActivityRecord r,
        ActivityRecord sourceRecord, int startFlags, boolean doResume,
        Bundle options) {
    //...
    //launchFlags为FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
    int launchFlags = intent.getFlags();
   //... 
   //没设置FLAG_ACTIVITY_PREVIOUS_IS_TOP,故此notTop为null        
    ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
            != 0 ? r : null;
   //startFlags未设置ActivityManager.START_FLAG_ONLY_IF_NEEDED
   //...  
   //sourceRecord为Launcher应用的Activity  launcher应用activity的启动模式为singleTask
   // 故此下面的3个条件分支的内容都不会执行  
    if (sourceRecord == null) {
        //... 
    } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
         //...
    } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
        //... 
    }
    //... 
    //r.resultTo不为null, launchFlags设置了FLAG_ACTIVITY_NEW_TASK,需要将r.resultTo置为null
    if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
        //... 
        r.resultTo = null;
    }         
    boolean addingToTask = false;
    boolean movedHome = false;
    TaskRecord reuseTask = null;
    //因为launchFlags为FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
    //故此下面的条件会满足, 也就是说只要从Launcher程序启动应用,下面这个条件肯定会满足
    if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
            (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        //... 
        if (r.resultTo == null) {
            //因为应用被第一次启动,故此找不到相关task,taskTop则为null
            ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
                    ? findTaskLocked(intent, r.info)
                    : findActivityLocked(intent, r.info);
            if (taskTop != null) {
              //... 这里面的内容不会执行
            }     
        }
    }
   //...
   //r.packageName != null
    if (r.packageName != null) {
        //如果被启动的Activity正好是栈顶的Activity,
        //并且被启动的Activity启动模式是singleTop或者singleTask,
        //则不用将新的ActivityRecord加入到栈里
        //top Activity为Launcher应用的Activity 
        ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
        if (top != null && r.resultTo == null) {
            //top.realActivity.equals(r.realActivity)不满足
            if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                //... 这里的代码不会被执行 
            }
        }
    } else {
        //...
    } 
    boolean newTask = false;
    boolean keepCurTransition = false;
    // 此时 r.resultTo为null addingToTask为false  launchFlags设置了FLAG_ACTIVITY_NEW_TASK
    if (r.resultTo == null && !addingToTask
            && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
        if (reuseTask == null) {
            // todo: should do better management of integers.
            mService.mCurTask++;
            if (mService.mCurTask <= 0) {
                mService.mCurTask = 1;
            }
            //创建新task
            r.setTask(new TaskRecord(mService.mCurTask, r.info, intent), null, true);
            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
                    + " in new task " + r.task);
        } else {
           //...这里的代码会执行
        }
        newTask = true;
        if (!movedHome) {
            moveHomeToFrontFromLaunchLocked(launchFlags);
        }
    } else if (sourceRecord != null) {
         //... 这里的代码不会被执行
    } else {
       //...这里的代码不会被执行
    }
    //... 
    startActivityLocked(r, newTask, doResume, keepCurTransition, options);
    return ActivityManager.START_SUCCESS;
}

 

2)跳转至应用内Activity时

会将新的ActivityRecord加入已有的task,任务调度执行如下所示:

final int startActivityUncheckedLocked(ActivityRecord r,
        ActivityRecord sourceRecord, int startFlags, boolean doResume,
        Bundle options) {
    //此时launchFlags为0 
    int launchFlags = intent.getFlags();
    //notTop为null    
    ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
            != 0 ? r : null;
    //startFlags未设置ActivityManager.START_FLAG_ONLY_IF_NEEDED
    //...     
    if (sourceRecord == null) {
       //...这里的代码不会被执行
    } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
      //...这里的代码不会被执行   
    } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
      //...这里的代码不会被执行     
    }
    //r.resultTo != null 但是launchFlags未设置FLAG_ACTIVITY_NEW_TASK
    if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
       //... 这里的代码不执行  
    }
    boolean addingToTask = false;
    boolean movedHome = false;
    TaskRecord reuseTask = null;
    //launchFlags为0 r的启动模式为standard 故此下面的逻辑都不会执行
    if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
            (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        //... 这里的代码不执行
    }
   //...
    if (r.packageName != null) {
        //top 是ActivityA 的ActivityRecord,
        //但是被启动的Activity和top不是同一个Activity
        ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
        if (top != null && r.resultTo == null) {
            if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                 //...这里的代码不执行
            }
        }
    } else {
        //...这里的代码不执行
    }
    boolean newTask = false;
    boolean keepCurTransition = false;
    //此时 r.resultTo !=null  sourceRecord != null addingToTask=false
    if (r.resultTo == null && !addingToTask
            && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
        //...这里的代码不执行         
    } else if (sourceRecord != null) {
        if (!addingToTask &&
                (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
             //... 这里的代码不执行
        } else if (!addingToTask &&
                (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
             //... 这里的代码不执行 
        }
        //添加到现有的task 
        r.setTask(sourceRecord.task, sourceRecord.thumbHolder, false);
        //... 
    } else {
        //... 这里的代码不执行 
    }
    //...
    return ActivityManager.START_SUCCESS;
}

3)然后按Home键,再打开应用程序

此时会先找到已有的相关task,并显示栈顶的Activity,任务调度执行如下所示:

final int startActivityUncheckedLocked(ActivityRecord r,
        ActivityRecord sourceRecord, int startFlags, boolean doResume,
        Bundle options) {
    //...
    //launchFlags为FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 
    int launchFlags = intent.getFlags();
    //notTop为null    
    ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
            != 0 ? r : null;
    //startFlags未设置ActivityManager.START_FLAG_ONLY_IF_NEEDED
    //...         
    if (sourceRecord == null) {
       //...这里的代码不会被执行
    } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        //...这里的代码不会被执行  
    } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
       //...这里的代码不会被执行 
    }
    //此时 r.resultTo != null launchFlags设置了FLAG_ACTIVITY_NEW_TASK
    if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
        //...
        r.resultTo = null;
    } 
    boolean addingToTask = false;
    boolean movedHome = false;
    TaskRecord reuseTask = null;
    //此时launchFlags设置了FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 
    if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
            (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        //此时 r.resultTo == null
        if (r.resultTo == null) {
            //此时已有相关task,并且task 栈的栈顶是Activity B的ActivityRecord
            //故此taskTop为Activity B的ActivityRecord 
            ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
                    ? findTaskLocked(intent, r.info)
                    : findActivityLocked(intent, r.info);
            if (taskTop != null) {
                //... 
                // 此时curTop是Launcher应用的Activity的ActivityRecord  
                ActivityRecord curTop = topRunningNonDelayedActivityLocked(notTop);
                if (curTop != null && curTop.task != taskTop.task) {
                    r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
                    //此时Launcher应用的task在栈顶,故此callerAtFront为true,
                    //此时会把被启动的应用的task移至栈顶
                    boolean callerAtFront = sourceRecord == null
                            || curTop.task == sourceRecord.task;
                    if (callerAtFront) {
                        // We really do want to push this one into the
                        // user's face, right now.
                        movedHome = true;
                        moveHomeToFrontFromLaunchLocked(launchFlags);
                        moveTaskToFrontLocked(taskTop.task, r, options);
                        options = null;
                    }
                }
                //此时launchFlags设置了FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
                //此时需要重置task 重置完后 taskTop为ActivityB的ActivityRecord   
                if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
                    taskTop = resetTaskIfNeededLocked(taskTop, r);
                }
                //startFlags为0
                if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED)  != 0) {
                    //... 这些代码都不会被执行 
                } 
                //根据launchFlags和被启动的activity的信息 设置resueTask addingTask变量的值                  
                //没设置 Intent.FLAG_ACTIVITY_CLEAR_TASK
                if ((launchFlags &
                          (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
                          == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
                      //... 这些代码都不会被执行  
                 } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
                          || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
                          || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                      //... 这些代码都不会被执行  
                 } else if (r.realActivity.equals(taskTop.task.realActivity)) {
                      //... 这些代码都不会被执行   
                 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
                       //因为从Launcher程序启动时launchFlags设置了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
                       //所以不会进入该分支
                       //... 这些代码都不会被执行   
                  } else if (!taskTop.task.rootWasReset) {
                       //... 这些代码都不会被执行    
                  }  
                  //此时addingToTask为false,reuseTask为null,故此显示栈顶Actvity即可
                  if (!addingToTask && reuseTask == null) {
                      // We didn't do anything...  but it was needed (a.k.a., client
                      // don't use that intent!)  And for paranoia, make
                      // sure we have correctly resumed the top activity.
                      if (doResume) {
                          resumeTopActivityLocked(null, options);
                      } else {
                          ActivityOptions.abort(options);
                      }
                      return ActivityManager.START_TASK_TO_FRONT;
                  } 
            }
        }
    }
   //... 以下代码都不会被执行    
}

 

实际场景2:

应用内有两个Activity,A和B,A为第应用入口Activity,从A可跳转至B,A的启动模式都为standard,B的启动模式为singleTop

此时已从Launchenr程序打开应用,启动了Actvity A,再从A跳转至B,此时的任务调度情况:

此时不会创建新的Task,而是将B的ActivityRecord加入到A所在的task里

任务调度执行如下所示:

final int startActivityUncheckedLocked(ActivityRecord r,
        ActivityRecord sourceRecord, int startFlags, boolean doResume,
        Bundle options) {
    //...  
    //此时launcheFlags为0
    int launchFlags = intent.getFlags();      
    //notTop为null
    ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
            != 0 ? r : null;
    //默认情况下startFlags不会设置START_FLAG_ONLY_IF_NEEDED    
    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
        //...这里的代码不会执行
    }    
    //r.launchMode = ActivityInfo.LAUNCH_SINGLE_TASK 
    if (sourceRecord == null) {
       //这里的代码不会执行  
    } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        //这里的代码不会执行    
    } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
        launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
    }
    //此时r.resultTo!=null launchFlags设置了Intent.FLAG_ACTIVITY_NEW_TASK
    if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
       //...
        r.resultTo = null;
    }       
    //addingToTask如果为true表示正在添加至某个task,后续需要将r添加至sourceRecord所在的task
    boolean addingToTask = false;
    //movedHome表示是否移动home task
    boolean movedHome = false; 
    TaskRecord reuseTask = null;       
    if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
            (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        //此时 r.resultTo = null
        if (r.resultTo == null) {
            //此时找到的taskTop是Activity A的ActivityRecord,
            //因为Actvity B和A的ActivityRecord所在的Task是相关的
            ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
                    ? findTaskLocked(intent, r.info)
                    : findActivityLocked(intent, r.info);
            //找到了相关task        
            if (taskTop != null) {
                //重设task的intent
                if (taskTop.task.intent == null) {
                     //...
                }
                //此时找到的task已在栈顶
                ActivityRecord curTop = topRunningNonDelayedActivityLocked(notTop);
                if (curTop != null && curTop.task != taskTop.task) {
                    //... 这里的代码不会执行 
                }
                //launchFlags为0
                if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
                    taskTop = resetTaskIfNeededLocked(taskTop, r);
                }
                //... 一般情况下startFlags 不会设置 START_FLAG_ONLY_IF_NEEDED
                if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED)  != 0) {
                    //...
                } 
                // ==================== begin
                // launchFlags此时为0
                if ((launchFlags &
                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
                     //...这里的代码不执行
                } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
                        || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
                        || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                    // r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
                    // 故此会进入该分支
                    //因为B还从未启动,故此得到的top为null
                    ActivityRecord top = performClearTaskLocked(
                            taskTop.task.taskId, r, launchFlags);
                    if (top != null) {
                        //...这里的代码不执行 
                    } else { 
                        addingToTask = true; 
                        sourceRecord = taskTop;
                    }
                } else if (r.realActivity.equals(taskTop.task.realActivity)) {
                     //...这里的代码不执行 
                } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
                     //...这里的代码不执行 
                } else if (!taskTop.task.rootWasReset) {
                     //...这里的代码不执行 
                }
                // ==================== end     
                // 此时 addingToTask为true          
                if (!addingToTask && reuseTask == null) {
                     //...这里的代码不执行 
                }
            }
        }
    } 
    //... 
    if (r.packageName != null) { 
        ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
        if (top != null && r.resultTo == null) {
            //此时task还没有B的ActivityRecord,故此不会进入下述分支
            if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                 //...这里的代码不执行
            }
        }
    } else {
           //...这里的代码不执行
    }
    boolean newTask = false;
    boolean keepCurTransition = false;
    // 此时 r.resultTo == null addingToTask为true sourceRecord != null
    if (r.resultTo == null && !addingToTask
            && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
         //...这里的代码不执行 
    } else if (sourceRecord != null) {
        if (!addingToTask &&
                (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
               //...这里的代码不执行 
        } else if (!addingToTask &&
                (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
               //...这里的代码不执行 
        }
        //将B的ActivityRecord加入A的ActivityRecord所在的Task里 
        r.setTask(sourceRecord.task, sourceRecord.thumbHolder, false);
        //... 
    } else {
         //...这里的代码不执行
    }
    //...
    startActivityLocked(r, newTask, doResume, keepCurTransition, options);
    return ActivityManager.START_SUCCESS;
}

 

总结

从上面的分析可以看出来,Activity和Task的调度算法非常复杂,需结合实际场景才好分析,只有这样才知道是否需要新建Task,还是将新的ActivityRecord加入到已有的Task里,不过我们如果能理解启动模式的一些特点,对理解调度算法会有很大帮助。

大家可以结合下述场景分析调度算法:

1.从通知栏启动Activity:

假设应用有Activity A ,Activity A已启动,

此时发了一个通知,该通知用于启动Activity A,启动Activity A时不加任何特殊flag

点击通知,针对以下情况对任务调度情况进行分析:

  1. Activity A的启动模式为standard

  2. Activity A的启动模式为singleTop

  3. Activity A的启动模式为singleTask

  4. Activity A的启动模式为singleInstance

2.跨应用跳转Activity

假设应用app1有一个Activity A,另一个应用app2有一个Activity B

Activity A可跳转至Activity B

因为Activity A和Actiivty B在不同应用,所以Activity的taskffinity必然不同

现在Activity A已启动,跳转至Activity B,

针对以下4种情况分析跳转之后的Activity Task情况

  1. Activity B的启动模式为standard

  2. Activity B的启动模式为singleTop

  3. Activity B的启动模式为singleTask

  4. Activity B的启动模式为singleInstance

如果大家对上述场景分析有兴趣的话,可以在评论里一起探讨结果。



 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部