ActivityStackSupervisor.StartActivityUncheckedLocked()函数分析

一、谁调用的它?

ASS.StartActivityLocked()函数调用的它。注意这里是ASS.StartActivityLocked(),而ASS.StartActivityUncheckedLocked()在函数结尾会进入AS.StartActivityLocked(),注意两者不是相同的函数。
ASS.StartActivityLocked()函数主要作用:创建ActivityRecord。

概要分析:

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
 ......
//在该函数中,将上一步得到的Activity信息ActivityInfo aInfo传进来,并创建ActivityRecord
 final int startActivityLocked(IApplicationThread caller,
      Intent intent, String resolvedType,
      Uri[] grantedUriPermissions,
      int grantedMode, ActivityInfo aInfo, IBinder resultTo,
             String resultWho, int requestCode,
      int callingPid, int callingUid, boolean onlyIfNeeded,
      boolean componentSpecified) 
{
            int err = START_SUCCESS;

// 从传进来的参数caller得到调用者的进程信息,并保存在callerApp变量中,这里就是Launcher应用程序的进程信息了。
//其中,IApplicationThread caller是Launcher的Binder对象,ProcessRecord callerApp是要启动的程序的进程Record。
            ProcessRecord callerApp = null;
  if (caller != null)
  {
  callerApp = mService.getRecordForAppLocked(caller);
  if (callerApp != null)
  {
    callingPid = callerApp.pid;
    callingUid = callerApp.info.uid;
   } 
  else 
  {
    ......
   }
  }

  ......
//参数resultTo是Launcher这个Activity里面的一个Binder对象,通过它可以获得Launcher这个Activity的相关信息,保存在sourceRecord变量中。
说明: IBinder resultTo:Launcher这个Activity里面的一个Binder对象; 
            String resultWho:additional identifier for use of resultT。
            ActivityRecord sourceRecord :记录Launcher的Activity的ActivityRecord。
  ActivityRecord sourceRecord = null;
  ActivityRecord resultRecord = null;
  if (resultTo != null) {
   int index = indexOfTokenLocked(resultTo);
   
   ......
    
   if (index >= 0) {
    sourceRecord = (ActivityRecord)mHistory.get(index);
    if (requestCode >= 0 && !sourceRecord.finishing) {
     ......
    }
   }
//从intent获取Flags。
  int launchFlags = intent.getFlags();

  if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
   && sourceRecord != null) {
   ......
  }
  ......

//创建即将要启动的Activity的相关信息,并保存在r变量中。
  ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid,
   intent, resolvedType, aInfo, mService.mConfiguration,
   resultRecord, resultWho, requestCode, componentSpecified);
  ......
//接着调用startActivityUncheckedLocked函数进行下一步操作。 
  return startActivityUncheckedLocked(r, sourceRecord,
   grantedUriPermissions, grantedMode, onlyIfNeeded, true);
 }
 ......

}



二、它是用来干什么的?

作用:为新开启的Activity创建Task,并将Task保存在ActivityRecord r.task域中。


三、具体分析:


分析(1):判断是否需要创建新的Task,设置launchFlags。



    final int startActivityUncheckedLocked(ActivityRecord r,
            ActivityRecord sourceRecord, int startFlags, boolean doResume,
            Bundle options) {
        final Intent intent = r.intent;
        final int callingUid = r.launchedFromUid;
        int launchFlags = intent.getFlags();
        // We'll invoke onUserLeaving before onPause only if the launching
        // activity did not explicitly state that this is an automated launch.
//如果lauching Activity 没有明确指出这个Activity要自动启动的话,我们就要在执行onPause函数之前执行onUseLeaving函数
        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.
//如果laucher 没有要求在此时立即启动该Activity,那么 r.delayedResume = true(表示可以延迟resume),当查找最上层正在运行的Activity的时候就可以跳过它了。
        if (!doResume) {
            r.delayedResume = true;
        }
        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.
//ActivityRecord checkedCaller优先等于sourceRecord,其次选择正在运行的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;
            }
        }
//下面是三种需要创建新的TASK的情况:(1)sourceRecord=null说明要启动的Activity并不是由一个程序启动的,这时候我们总是启动一个新的TASK。(forcing " +  "Intent.FLAG_ACTIVITY_NEW_TASK);(2)Launcher的Activity是SingleInstance模式(sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE);(3)r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK。
统一处理:设置launchFlags标志。(launchFlags标志决定着是否新创建Task等。)
        if (sourceRecord == null) {
            // This activity is not being started from another... in this
            // case we -always- start a new task.
            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
                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 (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
            // The activity being started is a single instance... it always
            // gets launched into its own task.
            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
        }
//创建ActivityStack sourceStack表示sourceRecord所在的TASK所在的Stack。并通过判断sourceRecord是否还在以及如果在的话,状态如何,来设置launchFlags标志。
        final 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.
                //如果sourceRecord已经处于finishing状态,那么他所在的Task就很有可能已经为空或者即将为空。
                //我们就不能盲目throw it in to that 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;
                }
                sourceRecord = null;
                sourceStack = null;
            } else {
                sourceStack = sourceRecord.task.stack; //sourceRecord依然健在
            }
        } else {
            sourceStack = null;//sourceRecord == null
        }
//如果新的Activity要新创建Task而启动,而且原先的Activity需要返回结果,这种情况下,调用函数r.resultTo.task.stack.sendActivityResultLocked()将 Activity.RESULT_CANCELED结果返回给launcher,并将resultTo置为null,resultTo的使命结束了。
        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;
        }
        boolean addingToTask = false;
        boolean movedHome = false;
        TaskRecord reuseTask = null;
        ActivityStack targetStack;




分析(2):如果不启动新的Task,那么寻找Activity所属的Task并移到前台。



 
       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 bring to front is requested, and no result is requested, and
            // we can find a task that was started with this same
            // component, then instead of launching bring that one to the front.
//从所有Stack中的所有Task中的Activity中查找看能否找到要启动的Activity,根据要启动的Activity启动模式是否是SingleInstance所采用的搜索方法是不一样的。
            if (r.resultTo == null) {
//检查是否有Task需要被带到前台。如果检测到就赋值给ActivityRecord intentActivity,就不需要启动新的TASK了,否则,intentActivity为空,需要创建新的TASK。这里的intentActivity就是老罗分析里面的taskTop。
                // 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.
                ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
                        ? findTaskLocked(r)
                        : findActivityLocked(intent, r.info);
//intentActivity 所在的TASK就是要启动的Activity所在的Task,要启动的Activity所在的Stack targetStack就是intentActivity所在的Stack。
                if (intentActivity != null) {
                    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);
                    moveHomeStack(targetStack.isHomeStack());
                    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(intent, r.info);
                    }
                    // 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.
                            movedHome = true;
                            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.mOnTopOfHome = true;
                            }
//这一步,将已经存在的我们的目标Task终于被移动到了前台!参数intentActivity.task就是我们搜索出来的我们要启动的Activity所在的Task,r就是我们要启动的ActivityRecord。
                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
                            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);
                        }
                        if (r.task == null) Slog.v(TAG,
                                "startActivityUncheckedLocked: task left null",
                                new RuntimeException("here").fillInStackTrace());
                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                    }
//如果Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK被置位,那么将除此之外的所有Task都清除掉:
reuseTask.performClearTaskLocked();
                    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.intent, r.info);
                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                        // 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.intent, r.info);
                            }
                            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
                                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
                                && intentActivity.realActivity.equals(r.realActivity)) {
                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
                                    intentActivity.task);
                            if (intentActivity.frontOfTask) {
                                intentActivity.task.setIntent(r.intent, r.info);
                            }
                            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.intent, r.info);
                    }
                    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);
                        }
                        if (r.task == null) Slog.v(TAG,
                            "startActivityUncheckedLocked: task left null",
                            new RuntimeException("here").fillInStackTrace());
                        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);
//  这段代码的逻辑是看一下,当前在堆栈顶端的Activity是否就是即将要启动的Activity,有些情况下,如果即将要启动的Activity就在堆栈的顶端,那么,就不会重新启动这个Activity的别一个实例了,具体可以参考官方网站http://developer.android.com/reference/android/content/pm/ActivityInfo.html。
        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.
            ActivityStack topStack = getFocusedStack();
            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
            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
                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
                            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!
                                if (r.task == null) Slog.v(TAG,
                                    "startActivityUncheckedLocked: task left null",
                                    new RuntimeException("here").fillInStackTrace());
                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                            }
                            top.deliverNewIntentLocked(callingUid, r.intent);
                            if (r.task == null) Slog.v(TAG,
                                "startActivityUncheckedLocked: task left null",
                                new RuntimeException("here").fillInStackTrace());
                            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);
            if (r.task == null) Slog.v(TAG,
                "startActivityUncheckedLocked: task left null",
                new RuntimeException("here").fillInStackTrace());
            return ActivityManager.START_CLASS_NOT_FOUND;
        }


分析(3):创建新的Task,及后续处理。



       
 boolean newTask = false;
        boolean keepCurTransition = false;
        // Should this be considered a new task?
        if (r.resultTo == null && !addingToTask
                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
            targetStack = adjustStackFocus(r);
            moveHomeStack(targetStack.isHomeStack());

//在此时,若前面的reuseTask为空,在targetStack中创建新的Task。
//r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),null, true);

            if (reuseTask == null) {
                r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
                        null, true);
                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
                        r.task);
            } else {
                r.setTask(reuseTask, reuseTask, true);
            }
            newTask = true;//newTask置位,说明使用了新的Task。
            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.mOnTopOfHome = true;
                }
            }
        } else if (sourceRecord != null) {
            TaskRecord sourceTask = sourceRecord.task;
            targetStack = sourceTask.stack;
            moveHomeStack(targetStack.isHomeStack());
            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);
                    if (r.task == null) Slog.w(TAG,
                        "startActivityUncheckedLocked: task left null",
                        new RuntimeException("here").fillInStackTrace());
                    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, sourceRecord.thumbHolder, false);
            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
                    + " in existing task " + r.task + " from source " + sourceRecord);
        } 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);
            moveHomeStack(targetStack.isHomeStack());
            ActivityRecord prev = targetStack.topActivity();
            r.setTask(prev != null ? prev.task
                    : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
                    null, true);
            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
                    + " in new guessed " + r.task);
        }
//赋权限,这里的mService就是AMS
        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
                intent, r.getUriPermissionsLocked());
        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;
 //最后就进入startActivityLocked(r, newTask, doResume)进一步处理了。
        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
        mService.setFocusedActivityLocked(r);
        return ActivityManager.START_SUCCESS;
    }


















你可能感兴趣的:(安卓源码分析)