zoukankan      html  css  js  c++  java
  • android Activity启动过程(四)startActivityUncheckedLocked

        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

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



  • 相关阅读:
    js获取cookie
    js 获取父页元素
    【HDU4571 Travel in time】二维多状态spfa
    【HDU4360】 最短路变形
    百度人脸识别模块使用分享
    APICloud · 跨越2018,技术改变世界
    Android平台targetSdkVersion设置及动态权限
    UIPullRefreshFlash模块demo示例
    webToImage (网页转图片)模块试用分享
    生成带二维码图片并通过微信分享
  • 原文地址:https://www.cnblogs.com/mingfeng002/p/9188139.html
Copyright © 2011-2022 走看看