1. final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,
  2. IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
  3. boolean doResume, Bundle options, TaskRecord inTask) {
  4. final Intent intent = r.intent;
  5. final int callingUid = r.launchedFromUid;
  6.  
  7. // In some flows in to this function, we retrieve the task record and hold on to it
  8. // without a lock before calling back in to here... so the task at this point may
  9. // not actually be in recents. Check for that, and if it isn't in recents just
  10. // consider it invalid.
  11. if (inTask != null && !inTask.inRecents) {
  12. Slog.w(TAG, "Starting activity in task not in recents: " + inTask);
  13. inTask = null;
  14. }
  15.  
  16. final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
  17. final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
  18. final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
  19.  
  20. int launchFlags = intent.getFlags();
  21. if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
  22. (launchSingleInstance || launchSingleTask)) {
  23. // We have a conflict between the Intent and the Activity manifest, manifest wins.
  24. Slog.i(TAG, "Ignoring FLAG_ACTIVITY_NEW_DOCUMENT, launchMode is " +
  25. "\"singleInstance\" or \"singleTask\"");
  26. launchFlags &=
  27. ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
  28. } else {
  29. switch (r.info.documentLaunchMode) {
  30. case ActivityInfo.DOCUMENT_LAUNCH_NONE:
  31. break;
  32. case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
  33. launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
  34. break;
  35. case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
  36. launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
  37. break;
  38. case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
  39. launchFlags &= ~Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
  40. break;
  41. }
  42. }
  43.  
  44. final boolean launchTaskBehind = r.mLaunchTaskBehind
  45. && !launchSingleTask && !launchSingleInstance
  46. && (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
  47.  
  48. if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
  49. // For whatever reason this activity is being launched into a new
  50. // task... yet the caller has requested a result back. Well, that
  51. // is pretty messed up, so instead immediately send back a cancel
  52. // and let the new task continue launched as normal without a
  53. // dependency on its originator.
  54. Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
  55. r.resultTo.task.stack.sendActivityResultLocked(-1,
  56. r.resultTo, r.resultWho, r.requestCode,
  57. Activity.RESULT_CANCELED, null);
  58. r.resultTo = null;
  59. }
  60.  
  61. if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
  62. launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
  63. }
  64.  
  65. // If we are actually going to launch in to a new task, there are some cases where
  66. // we further want to do multiple task.
  67. if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
  68. if (launchTaskBehind
  69. || r.info.documentLaunchMode == ActivityInfo.DOCUMENT_LAUNCH_ALWAYS) {
  70. launchFlags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
  71. }
  72. }
  73.  
  74. // We'll invoke onUserLeaving before onPause only if the launching
  75. // activity did not explicitly state that this is an automated launch.
  76. mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
  77. if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
  78.  
  79. // If the caller has asked not to resume at this point, we make note
  80. // of this in the record so that we can skip it when trying to find
  81. // the top running activity.
  82. if (!doResume) {
  83. r.delayedResume = true;
  84. }
  85.  
  86. //如果从Launcher程序启动应用,launchFlags为 FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
  87. //否则一般情况下launcheFlags为0,除非启动Activity时设置了特殊的flag
  88. //启动Activity时默认不会设置FLAG_ACTIVITY_PREVIOUS_IS_TOP
  89. //故此notTop默认情况下会是null
  90.  
  91. ActivityRecord notTop =
  92. (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
  93.  
  94. // If the onlyIfNeeded flag is set, then we can do this if the activity
  95. // being launched is the same as the one making the call... or, as
  96. // a special case, if we do not know the caller then we count the
  97. // current top activity as the caller.
  98. //START_FLAG_ONLY_IF_NEEDED表示只有在需要的时候才启动目标Activity。也就是说如果调用者和被启动的是一个,那么就没有必要去进行重复的步骤了
  99. if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
  100. //默认情况下这里的代码不会执行
  101. ActivityRecord checkedCaller = sourceRecord;
  102. if (checkedCaller == null) {
  103. checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
  104. }
  105. if (!checkedCaller.realActivity.equals(r.realActivity)) {
  106. // Caller is not the same as launcher, so always needed.
  107. startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
  108. }
  109. }
  110.  
  111. boolean addingToTask = false;
  112. TaskRecord reuseTask = null;
  113.  
  114. // If the caller is not coming from another activity, but has given us an
  115. // explicit task into which they would like us to launch the new activity,
  116. // then let's see about doing that.
  117. /*
  118. * 如果调用者不是来自另一个activity(不是在activity中调用startActivity),
  119. * 但是给了我们用于放入新activity的一个明确的task,将执行下面代码
  120. *
  121. * 我们往上追溯,发现inTask是 中 ActivityManagerService.startActivityAsUser()方法传递的null,
  122. * 所以if里面的不会执行
  123. */
  124. if (sourceRecord == null && inTask != null && inTask.stack != null) {
  125. final Intent baseIntent = inTask.getBaseIntent();
  126. final ActivityRecord root = inTask.getRootActivity();
  127. if (baseIntent == null) {
  128. ActivityOptions.abort(options);
  129. throw new IllegalArgumentException("Launching into task without base intent: "
  130. + inTask);
  131. }
  132.  
  133. // If this task is empty, then we are adding the first activity -- it
  134. // determines the root, and must be launching as a NEW_TASK.
  135. if (launchSingleInstance || launchSingleTask) {
  136. if (!baseIntent.getComponent().equals(r.intent.getComponent())) {
  137. ActivityOptions.abort(options);
  138. throw new IllegalArgumentException("Trying to launch singleInstance/Task "
  139. + r + " into different task " + inTask);
  140. }
  141. if (root != null) {
  142. ActivityOptions.abort(options);
  143. throw new IllegalArgumentException("Caller with inTask " + inTask
  144. + " has root " + root + " but target is singleInstance/Task");
  145. }
  146. }
  147.  
  148. // If task is empty, then adopt the interesting intent launch flags in to the
  149. // activity being started.
  150. if (root == null) {
  151. final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK
  152. | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT
  153. | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
  154. launchFlags = (launchFlags&~flagsOfInterest)
  155. | (baseIntent.getFlags()&flagsOfInterest);
  156. intent.setFlags(launchFlags);
  157. inTask.setIntent(r);
  158. addingToTask = true;
  159.  
  160. // If the task is not empty and the caller is asking to start it as the root
  161. // of a new task, then we don't actually want to start this on the task. We
  162. // will bring the task to the front, and possibly give it a new intent.
  163. } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
  164. addingToTask = false;
  165.  
  166. } else {
  167. addingToTask = true;
  168. }
  169.  
  170. reuseTask = inTask;
  171. } else {
  172. inTask = null;
  173. }
  174.  
  175. //根据activity的设置,如果满足下列条件,将launchFlags置为FLAG_ACTIVITY_NEW_TASK
  176. if (inTask == null) {
  177. if (sourceRecord == null) {
  178. // This activity is not being started from another... in this
  179. // case we -always- start a new task.
  180. //如果调用者为null,将launchFlags置为 创建一个新task
  181. if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
  182. Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
  183. "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
  184. launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
  185. }
  186. } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
  187. // The original activity who is starting us is running as a single
  188. // instance... this new activity it is starting must go on its
  189. // own task.
  190. launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
  191. } else if (launchSingleInstance || launchSingleTask) {
  192. // The activity being started is a single instance... it always
  193. // gets launched into its own task.
  194. launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
  195. }
  196. }
  197.  
  198. ActivityInfo newTaskInfo = null;
  199. Intent newTaskIntent = null;
  200. ActivityStack sourceStack;
  201. if (sourceRecord != null) {
  202. if (sourceRecord.finishing) {
  203. // If the source is finishing, we can't further count it as our source. This
  204. // is because the task it is associated with may now be empty and on its way out,
  205. // so we don't want to blindly throw it in to that task. Instead we will take
  206. // the NEW_TASK flow and try to find a task for it. But save the task information
  207. // so it can be used when creating the new task.
  208. if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
  209. Slog.w(TAG, "startActivity called from finishing " + sourceRecord
  210. + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
  211. launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
  212. newTaskInfo = sourceRecord.info;
  213. newTaskIntent = sourceRecord.task.intent;
  214. }
  215. sourceRecord = null;
  216. sourceStack = null;
  217. } else {
  218. sourceStack = sourceRecord.task.stack;
  219. }
  220. } else {
  221. sourceStack = null;
  222. }
  223.  
  224. boolean movedHome = false;
  225. ActivityStack targetStack;
  226.  
  227. intent.setFlags(launchFlags);
  228.  
  229. // We may want to try to place the new activity in to an existing task. We always
  230. // do this if the target activity is singleTask or singleInstance; we will also do
  231. // this if NEW_TASK has been requested, and there is not an additional qualifier telling
  232. // us to still place it in a new task: multi task, always doc mode, or being asked to
  233. // launch this as a new task behind the current one.
  234. /*
  235. * 我们尝试将新的activity放在一个现有的任务中。但是如果activity被要求是singleTask或者singleInstance,
  236. * 我们会将activity放入一个新的task中.下面的if中主要处理将目标进程置于栈顶,然后将目标activity显示
  237. */
  238. if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
  239. (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
  240. || launchSingleInstance || launchSingleTask) {
  241. // If bring to front is requested, and no result is requested and we have not
  242. // been given an explicit task to launch in to, and
  243. // we can find a task that was started with this same
  244. // component, then instead of launching bring that one to the front.
  245. //如果被开启的activity不是需要开启新的task,而是single instance或者singleTask,
  246. if (inTask == null && r.resultTo == null) {
  247. // See if there is a task to bring to the front. If this is
  248. // a SINGLE_INSTANCE activity, there can be one and only one
  249. // instance of it in the history, and it is always in its own
  250. // unique task, so we do a special search.
  251. //检查此activity是否已经开启了SINGLE_INSTANCE
  252. //findTaskLocked()方法用于查找目标activity所在的task
  253. ActivityRecord intentActivity = !launchSingleInstance ?
  254. findTaskLocked(r) : findActivityLocked(intent, r.info);
  255. if (intentActivity != null) {
  256. if (isLockTaskModeViolation(intentActivity.task)) {
  257. showLockTaskToast();
  258. Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
  259. return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
  260. }
  261. if (r.task == null) {
  262. r.task = intentActivity.task;
  263. }
  264. targetStack = intentActivity.task.stack;
  265. targetStack.mLastPausedActivity = null;
  266. if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
  267. + " from " + intentActivity);
  268. targetStack.moveToFront();
  269. if (intentActivity.task.intent == null) {
  270. // This task was started because of movement of
  271. // the activity based on affinity... now that we
  272. // are actually launching it, we can assign the
  273. // base intent.
  274. intentActivity.task.setIntent(r);
  275. }
  276. // If the target task is not in the front, then we need
  277. // to bring it to the front... except... well, with
  278. // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
  279. // to have the same behavior as if a new instance was
  280. // being started, which means not bringing it to the front
  281. // if the caller is not itself in the front.
  282. //如果目标不在栈顶,我们需要把它放到栈顶
  283. final ActivityStack lastStack = getLastStack();
  284. ActivityRecord curTop = lastStack == null?
  285. null : lastStack.topRunningNonDelayedActivityLocked(notTop);
  286. if (curTop != null && (curTop.task != intentActivity.task ||
  287. curTop.task != lastStack.topTask())) {
  288. r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
  289. if (sourceRecord == null || (sourceStack.topActivity() != null &&
  290. sourceStack.topActivity().task == sourceRecord.task)) {
  291. // We really do want to push this one into the
  292. // user's face, right now.
  293. if (launchTaskBehind && sourceRecord != null) {
  294. intentActivity.setTaskToAffiliateWith(sourceRecord.task);
  295. }
  296. movedHome = true;
  297. targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
  298. if ((launchFlags &
  299. (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
  300. == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
  301. // Caller wants to appear on home activity.
  302. intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
  303. }
  304. options = null;
  305. }
  306. }
  307. // If the caller has requested that the target task be
  308. // reset, then do so.
  309. if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
  310. intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
  311. }
  312. if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
  313. // We don't need to start a new activity, and
  314. // the client said not to do anything if that
  315. // is the case, so this is it! And for paranoia, make
  316. // sure we have correctly resumed the top activity.
  317. if (doResume) {
  318. resumeTopActivitiesLocked(targetStack, null, options);
  319. } else {
  320. ActivityOptions.abort(options);
  321. }
  322. return ActivityManager.START_RETURN_INTENT_TO_CALLER;
  323. }
  324. if ((launchFlags &
  325. (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
  326. == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
  327. // The caller has requested to completely replace any
  328. // existing task with its new activity. Well that should
  329. // not be too hard...
  330. reuseTask = intentActivity.task;
  331. reuseTask.performClearTaskLocked();
  332. reuseTask.setIntent(r);
  333. } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
  334. || launchSingleInstance || launchSingleTask) {
  335. //将task中位于目标activity上面的其他activitys清理掉
  336. // In this situation we want to remove all activities
  337. // from the task up to the one being started. In most
  338. // cases this means we are resetting the task to its
  339. // initial state.
  340. ActivityRecord top =
  341. intentActivity.task.performClearTaskLocked(r, launchFlags);
  342. if (top != null) {
  343. if (top.frontOfTask) {
  344. // Activity aliases may mean we use different
  345. // intents for the top activity, so make sure
  346. // the task now has the identity of the new
  347. // intent.
  348. top.task.setIntent(r);
  349. }
  350. ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
  351. r, top.task);
  352. top.deliverNewIntentLocked(callingUid, r.intent);
  353. } else {
  354. // A special case: we need to
  355. // start the activity because it is not currently
  356. // running, and the caller has asked to clear the
  357. // current task to have this activity at the top.
  358. addingToTask = true;
  359. // Now pretend like this activity is being started
  360. // by the top of its task, so it is put in the
  361. // right place.
  362. sourceRecord = intentActivity;
  363. }
  364. } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
  365. // In this case the top activity on the task is the
  366. // same as the one being launched, so we take that
  367. // as a request to bring the task to the foreground.
  368. // If the top activity in the task is the root
  369. // activity, deliver this new intent to it if it
  370. // desires.
  371. if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop)
  372. && intentActivity.realActivity.equals(r.realActivity)) {
  373. ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
  374. intentActivity.task);
  375. if (intentActivity.frontOfTask) {
  376. intentActivity.task.setIntent(r);
  377. }
  378. intentActivity.deliverNewIntentLocked(callingUid, r.intent);
  379. } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
  380. // In this case we are launching the root activity
  381. // of the task, but with a different intent. We
  382. // should start a new instance on top.
  383. addingToTask = true;
  384. sourceRecord = intentActivity;
  385. }
  386. } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
  387. // In this case an activity is being launched in to an
  388. // existing task, without resetting that task. This
  389. // is typically the situation of launching an activity
  390. // from a notification or shortcut. We want to place
  391. // the new activity on top of the current task.
  392. addingToTask = true;
  393. sourceRecord = intentActivity;
  394. } else if (!intentActivity.task.rootWasReset) {
  395. // In this case we are launching in to an existing task
  396. // that has not yet been started from its front door.
  397. // The current task has been brought to the front.
  398. // Ideally, we'd probably like to place this new task
  399. // at the bottom of its stack, but that's a little hard
  400. // to do with the current organization of the code so
  401. // for now we'll just drop it.
  402. intentActivity.task.setIntent(r);
  403. }
  404. if (!addingToTask && reuseTask == null) {
  405. // We didn't do anything... but it was needed (a.k.a., client
  406. // don't use that intent!) And for paranoia, make
  407. // sure we have correctly resumed the top activity.
  408. if (doResume) {
  409. targetStack.resumeTopActivityLocked(null, options);
  410. } else {
  411. ActivityOptions.abort(options);
  412. }
  413. return ActivityManager.START_TASK_TO_FRONT;
  414. }
  415. }
  416. }
  417. }
  418.  
  419. //String uri = r.intent.toURI();
  420. //Intent intent2 = new Intent(uri);
  421. //Slog.i(TAG, "Given intent: " + r.intent);
  422. //Slog.i(TAG, "URI is: " + uri);
  423. //Slog.i(TAG, "To intent: " + intent2);
  424.  
  425. if (r.packageName != null) {
  426. // If the activity being launched is the same as the one currently
  427. // at the top, then we need to check if it should only be launched
  428. // once.
  429. //如果被启动的Activity正好是栈顶的Activity,
  430. //并且被启动的Activity启动模式是singleTop或者singleTask,
  431. //则不用将新的ActivityRecord加入到栈里
  432. //top Activity为Launcher应用的Activity
  433. ActivityStack topStack = getFocusedStack();
  434. ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
  435. //当前处于堆栈顶端的task
  436. if (top != null && r.resultTo == null) {
  437. if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
  438. if (top.app != null && top.app.thread != null) {
  439. if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
  440. || launchSingleTop || launchSingleTask) {
  441. ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
  442. top.task);
  443. // For paranoia, make sure we have correctly
  444. // resumed the top activity.
  445. topStack.mLastPausedActivity = null;
  446. if (doResume) {
  447. resumeTopActivitiesLocked();
  448. }
  449. ActivityOptions.abort(options);
  450. if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
  451. // We don't need to start a new activity, and
  452. // the client said not to do anything if that
  453. // is the case, so this is it!
  454. return ActivityManager.START_RETURN_INTENT_TO_CALLER;
  455. }
  456. top.deliverNewIntentLocked(callingUid, r.intent);
  457. return ActivityManager.START_DELIVERED_TO_TOP;
  458. }
  459. }
  460. }
  461. }
  462.  
  463. } else {
  464. if (r.resultTo != null) {
  465. r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
  466. r.requestCode, Activity.RESULT_CANCELED, null);
  467. }
  468. ActivityOptions.abort(options);
  469. //包名为空,直接返回,没有找到
  470. return ActivityManager.START_CLASS_NOT_FOUND;
  471. }
  472.  
  473. boolean newTask = false;
  474. boolean keepCurTransition = false;
  475.  
  476. TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
  477. sourceRecord.task : null;
  478.  
  479. // Should this be considered a new task?
  480. if (r.resultTo == null && inTask == null && !addingToTask
  481. && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
  482. if (isLockTaskModeViolation(reuseTask)) {
  483. Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
  484. return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
  485. }
  486. newTask = true;
  487. targetStack = adjustStackFocus(r, newTask);
  488. if (!launchTaskBehind) {
  489. targetStack.moveToFront();
  490. }
  491. if (reuseTask == null) {
  492. r.setTask(targetStack.createTaskRecord(getNextTaskId(),
  493. newTaskInfo != null ? newTaskInfo : r.info,
  494. newTaskIntent != null ? newTaskIntent : intent,
  495. voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
  496. taskToAffiliate);
  497. if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
  498. r.task);
  499. } else {
  500. r.setTask(reuseTask, taskToAffiliate);
  501. }
  502. if (!movedHome) {
  503. if ((launchFlags &
  504. (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
  505. == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
  506. // Caller wants to appear on home activity, so before starting
  507. // their own activity we will bring home to the front.
  508. r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
  509. }
  510. }
  511. } else if (sourceRecord != null) {
  512. final TaskRecord sourceTask = sourceRecord.task;
  513. if (isLockTaskModeViolation(sourceTask)) {
  514. Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
  515. return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
  516. }
  517. targetStack = sourceTask.stack;
  518. targetStack.moveToFront();
  519. final TaskRecord topTask = targetStack.topTask();
  520. if (topTask != sourceTask) {
  521. targetStack.moveTaskToFrontLocked(sourceTask, r, options);
  522. } else {
  523. mWindowManager.moveTaskToTop(topTask.taskId);
  524. }
  525. if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
  526. // In this case, we are adding the activity to an existing
  527. // task, but the caller has asked to clear that task if the
  528. // activity is already running.
  529. ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
  530. keepCurTransition = true;
  531. if (top != null) {
  532. ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
  533. top.deliverNewIntentLocked(callingUid, r.intent);
  534. // For paranoia, make sure we have correctly
  535. // resumed the top activity.
  536. targetStack.mLastPausedActivity = null;
  537. if (doResume) {
  538. targetStack.resumeTopActivityLocked(null);
  539. }
  540. ActivityOptions.abort(options);
  541. return ActivityManager.START_DELIVERED_TO_TOP;
  542. }
  543. } else if (!addingToTask &&
  544. (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
  545. // In this case, we are launching an activity in our own task
  546. // that may already be running somewhere in the history, and
  547. // we want to shuffle it to the front of the stack if so.
  548. final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
  549. if (top != null) {
  550. final TaskRecord task = top.task;
  551. task.moveActivityToFrontLocked(top);
  552. ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
  553. top.updateOptionsLocked(options);
  554. top.deliverNewIntentLocked(callingUid, r.intent);
  555. targetStack.mLastPausedActivity = null;
  556. if (doResume) {
  557. targetStack.resumeTopActivityLocked(null);
  558. }
  559. return ActivityManager.START_DELIVERED_TO_TOP;
  560. }
  561. }
  562. // An existing activity is starting this new activity, so we want
  563. // to keep the new one in the same task as the one that is starting
  564. // it.
  565. r.setTask(sourceTask, null);
  566. if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
  567. + " in existing task " + r.task + " from source " + sourceRecord);
  568.  
  569. } else if (inTask != null) {
  570. // The calling is asking that the new activity be started in an explicit
  571. // task it has provided to us.
  572. //在调用者指定的确定的task中开启目标activity
  573. if (isLockTaskModeViolation(inTask)) {
  574. Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
  575. return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
  576. }
  577. targetStack = inTask.stack;
  578. targetStack.moveTaskToFrontLocked(inTask, r, options);
  579. targetStack.moveToFront();
  580. mWindowManager.moveTaskToTop(inTask.taskId);
  581.  
  582. // Check whether we should actually launch the new activity in to the task,
  583. // or just reuse the current activity on top.
  584. ActivityRecord top = inTask.getTopActivity();
  585. if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
  586. if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
  587. || launchSingleTop || launchSingleTask) {
  588. ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
  589. if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
  590. // We don't need to start a new activity, and
  591. // the client said not to do anything if that
  592. // is the case, so this is it!
  593. return ActivityManager.START_RETURN_INTENT_TO_CALLER;
  594. }
  595. top.deliverNewIntentLocked(callingUid, r.intent);
  596. return ActivityManager.START_DELIVERED_TO_TOP;
  597. }
  598. }
  599.  
  600. if (!addingToTask) {
  601. // We don't actually want to have this activity added to the task, so just
  602. // stop here but still tell the caller that we consumed the intent.
  603. ActivityOptions.abort(options);
  604. return ActivityManager.START_TASK_TO_FRONT;
  605. }
  606.  
  607. r.setTask(inTask, null);
  608. if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
  609. + " in explicit task " + r.task);
  610.  
  611. } else {
  612. // This not being started from an existing activity, and not part
  613. // of a new task... just put it in the top task, though these days
  614. // this case should never happen.
  615. targetStack = adjustStackFocus(r, newTask);
  616. targetStack.moveToFront();
  617. ActivityRecord prev = targetStack.topActivity();
  618. r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
  619. r.info, intent, null, null, true), null);
  620. mWindowManager.moveTaskToTop(r.task.taskId);
  621. if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
  622. + " in new guessed " + r.task);
  623. }
  624.  
  625. mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
  626. intent, r.getUriPermissionsLocked(), r.userId);
  627.  
  628. if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
  629. r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
  630. }
  631. if (newTask) {
  632. EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
  633. }
  634. ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
  635. targetStack.mLastPausedActivity = null;
  636. //继续调用目标ActivityStack的startActivityLocked()方法,这个方法没有返回值,执行完毕之后直接返回START_SUCCESS
  637. targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
  638. if (!launchTaskBehind) {
  639. // Don't set focus on an activity that's going to the back.
  640. mService.setFocusedActivityLocked(r);
  641. }
  642. return ActivityManager.START_SUCCESS;
  643. }
实际场景分析

实际场景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,任务调度执行如下所示:

  1. final int startActivityUncheckedLocked(ActivityRecord r,
  2. ActivityRecord sourceRecord, int startFlags, boolean doResume,
  3. Bundle options) {
  4. //...
  5. //launchFlags为FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
  6. int launchFlags = intent.getFlags();
  7. //...
  8. //没设置FLAG_ACTIVITY_PREVIOUS_IS_TOP,故此notTop为null
  9. ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
  10. != 0 ? r : null;
  11. //startFlags未设置ActivityManager.START_FLAG_ONLY_IF_NEEDED
  12. //...
  13. //sourceRecord为Launcher应用的Activity launcher应用activity的启动模式为singleTask
  14. // 故此下面的3个条件分支的内容都不会执行
  15. if (sourceRecord == null) {
  16. //...
  17. } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
  18. //...
  19. } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
  20. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
  21. //...
  22. }
  23. //...
  24. //r.resultTo不为null, launchFlags设置了FLAG_ACTIVITY_NEW_TASK,需要将r.resultTo置为null
  25. if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
  26. //...
  27. r.resultTo = null;
  28. }
  29. boolean addingToTask = false;
  30. boolean movedHome = false;
  31. TaskRecord reuseTask = null;
  32. //因为launchFlags为FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
  33. //故此下面的条件会满足, 也就是说只要从Launcher程序启动应用,下面这个条件肯定会满足
  34. if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
  35. (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
  36. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
  37. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
  38. //...
  39. if (r.resultTo == null) {
  40. //因为应用被第一次启动,故此找不到相关task,taskTop则为null
  41. ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
  42. ? findTaskLocked(intent, r.info)
  43. : findActivityLocked(intent, r.info);
  44. if (taskTop != null) {
  45. //... 这里面的内容不会执行
  46. }
  47. }
  48. }
  49. //...
  50. //r.packageName != null
  51. if (r.packageName != null) {
  52. //如果被启动的Activity正好是栈顶的Activity,
  53. //并且被启动的Activity启动模式是singleTop或者singleTask,
  54. //则不用将新的ActivityRecord加入到栈里
  55. //top Activity为Launcher应用的Activity
  56. ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
  57. if (top != null && r.resultTo == null) {
  58. //top.realActivity.equals(r.realActivity)不满足
  59. if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
  60. //... 这里的代码不会被执行
  61. }
  62. }
  63. } else {
  64. //...
  65. }
  66. boolean newTask = false;
  67. boolean keepCurTransition = false;
  68. // 此时 r.resultTo为null addingToTask为false launchFlags设置了FLAG_ACTIVITY_NEW_TASK
  69. if (r.resultTo == null && !addingToTask
  70. && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
  71. if (reuseTask == null) {
  72. // todo: should do better management of integers.
  73. mService.mCurTask++;
  74. if (mService.mCurTask <= 0) {
  75. mService.mCurTask = 1;
  76. }
  77. //创建新task
  78. r.setTask(new TaskRecord(mService.mCurTask, r.info, intent), null, true);
  79. if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
  80. + " in new task " + r.task);
  81. } else {
  82. //...这里的代码会执行
  83. }
  84. newTask = true;
  85. if (!movedHome) {
  86. moveHomeToFrontFromLaunchLocked(launchFlags);
  87. }
  88. } else if (sourceRecord != null) {
  89. //... 这里的代码不会被执行
  90. } else {
  91. //...这里的代码不会被执行
  92. }
  93. //...
  94. startActivityLocked(r, newTask, doResume, keepCurTransition, options);
  95. return ActivityManager.START_SUCCESS;
  96. }

2)跳转至应用内Activity时

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

  1. final int startActivityUncheckedLocked(ActivityRecord r,
  2. ActivityRecord sourceRecord, int startFlags, boolean doResume,
  3. Bundle options) {
  4. //此时launchFlags为0
  5. int launchFlags = intent.getFlags();
  6. //notTop为null
  7. ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
  8. != 0 ? r : null;
  9. //startFlags未设置ActivityManager.START_FLAG_ONLY_IF_NEEDED
  10. //...
  11. if (sourceRecord == null) {
  12. //...这里的代码不会被执行
  13. } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
  14. //...这里的代码不会被执行
  15. } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
  16. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
  17. //...这里的代码不会被执行
  18. }
  19. //r.resultTo != null 但是launchFlags未设置FLAG_ACTIVITY_NEW_TASK
  20. if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
  21. //... 这里的代码不执行
  22. }
  23. boolean addingToTask = false;
  24. boolean movedHome = false;
  25. TaskRecord reuseTask = null;
  26. //launchFlags为0 r的启动模式为standard 故此下面的逻辑都不会执行
  27. if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
  28. (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
  29. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
  30. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
  31. //... 这里的代码不执行
  32. }
  33. //...
  34. if (r.packageName != null) {
  35. //top 是ActivityA 的ActivityRecord,
  36. //但是被启动的Activity和top不是同一个Activity
  37. ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
  38. if (top != null && r.resultTo == null) {
  39. if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
  40. //...这里的代码不执行
  41. }
  42. }
  43. } else {
  44. //...这里的代码不执行
  45. }
  46. boolean newTask = false;
  47. boolean keepCurTransition = false;
  48. //此时 r.resultTo !=null sourceRecord != null addingToTask=false
  49. if (r.resultTo == null && !addingToTask
  50. && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
  51. //...这里的代码不执行
  52. } else if (sourceRecord != null) {
  53. if (!addingToTask &&
  54. (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
  55. //... 这里的代码不执行
  56. } else if (!addingToTask &&
  57. (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
  58. //... 这里的代码不执行
  59. }
  60. //添加到现有的task
  61. r.setTask(sourceRecord.task, sourceRecord.thumbHolder, false);
  62. //...
  63. } else {
  64. //... 这里的代码不执行
  65. }
  66. //...
  67. return ActivityManager.START_SUCCESS;
  68. }

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

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

  1. final int startActivityUncheckedLocked(ActivityRecord r,
  2. ActivityRecord sourceRecord, int startFlags, boolean doResume,
  3. Bundle options) {
  4. //...
  5. //launchFlags为FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
  6. int launchFlags = intent.getFlags();
  7. //notTop为null
  8. ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
  9. != 0 ? r : null;
  10. //startFlags未设置ActivityManager.START_FLAG_ONLY_IF_NEEDED
  11. //...
  12. if (sourceRecord == null) {
  13. //...这里的代码不会被执行
  14. } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
  15. //...这里的代码不会被执行
  16. } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
  17. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
  18. //...这里的代码不会被执行
  19. }
  20. //此时 r.resultTo != null launchFlags设置了FLAG_ACTIVITY_NEW_TASK
  21. if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
  22. //...
  23. r.resultTo = null;
  24. }
  25. boolean addingToTask = false;
  26. boolean movedHome = false;
  27. TaskRecord reuseTask = null;
  28. //此时launchFlags设置了FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
  29. if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
  30. (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
  31. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
  32. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
  33. //此时 r.resultTo == null
  34. if (r.resultTo == null) {
  35. //此时已有相关task,并且task 栈的栈顶是Activity B的ActivityRecord
  36. //故此taskTop为Activity B的ActivityRecord
  37. ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
  38. ? findTaskLocked(intent, r.info)
  39. : findActivityLocked(intent, r.info);
  40. if (taskTop != null) {
  41. //...
  42. // 此时curTop是Launcher应用的Activity的ActivityRecord
  43. ActivityRecord curTop = topRunningNonDelayedActivityLocked(notTop);
  44. if (curTop != null && curTop.task != taskTop.task) {
  45. r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
  46. //此时Launcher应用的task在栈顶,故此callerAtFront为true,
  47. //此时会把被启动的应用的task移至栈顶
  48. boolean callerAtFront = sourceRecord == null
  49. || curTop.task == sourceRecord.task;
  50. if (callerAtFront) {
  51. // We really do want to push this one into the
  52. // user's face, right now.
  53. movedHome = true;
  54. moveHomeToFrontFromLaunchLocked(launchFlags);
  55. moveTaskToFrontLocked(taskTop.task, r, options);
  56. options = null;
  57. }
  58. }
  59. //此时launchFlags设置了FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
  60. //此时需要重置task 重置完后 taskTop为ActivityB的ActivityRecord
  61. if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
  62. taskTop = resetTaskIfNeededLocked(taskTop, r);
  63. }
  64. //startFlags为0
  65. if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
  66. //... 这些代码都不会被执行
  67. }
  68. //根据launchFlags和被启动的activity的信息 设置resueTask addingTask变量的值
  69. //没设置 Intent.FLAG_ACTIVITY_CLEAR_TASK
  70. if ((launchFlags &
  71. (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
  72. == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
  73. //... 这些代码都不会被执行
  74. } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
  75. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
  76. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
  77. //... 这些代码都不会被执行
  78. } else if (r.realActivity.equals(taskTop.task.realActivity)) {
  79. //... 这些代码都不会被执行
  80. } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
  81. //因为从Launcher程序启动时launchFlags设置了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
  82. //所以不会进入该分支
  83. //... 这些代码都不会被执行
  84. } else if (!taskTop.task.rootWasReset) {
  85. //... 这些代码都不会被执行
  86. }
  87. //此时addingToTask为false,reuseTask为null,故此显示栈顶Actvity即可
  88. if (!addingToTask && reuseTask == null) {
  89. // We didn't do anything... but it was needed (a.k.a., client
  90. // don't use that intent!) And for paranoia, make
  91. // sure we have correctly resumed the top activity.
  92. if (doResume) {
  93. resumeTopActivityLocked(null, options);
  94. } else {
  95. ActivityOptions.abort(options);
  96. }
  97. return ActivityManager.START_TASK_TO_FRONT;
  98. }
  99. }
  100. }
  101. }
  102. //... 以下代码都不会被执行
  103. }
实际场景2:

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

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

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

任务调度执行如下所示:

  1. final int startActivityUncheckedLocked(ActivityRecord r,
  2. ActivityRecord sourceRecord, int startFlags, boolean doResume,
  3. Bundle options) {
  4. //...
  5. //此时launcheFlags为0
  6. int launchFlags = intent.getFlags();
  7. //notTop为null
  8. ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
  9. != 0 ? r : null;
  10. //默认情况下startFlags不会设置START_FLAG_ONLY_IF_NEEDED
  11. if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
  12. //...这里的代码不会执行
  13. }
  14. //r.launchMode = ActivityInfo.LAUNCH_SINGLE_TASK
  15. if (sourceRecord == null) {
  16. //这里的代码不会执行
  17. } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
  18. //这里的代码不会执行
  19. } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
  20. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
  21. launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
  22. }
  23. //此时r.resultTo!=null launchFlags设置了Intent.FLAG_ACTIVITY_NEW_TASK
  24. if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
  25. //...
  26. r.resultTo = null;
  27. }
  28. //addingToTask如果为true表示正在添加至某个task,后续需要将r添加至sourceRecord所在的task
  29. boolean addingToTask = false;
  30. //movedHome表示是否移动home task
  31. boolean movedHome = false;
  32. TaskRecord reuseTask = null;
  33. if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
  34. (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
  35. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
  36. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
  37. //此时 r.resultTo = null
  38. if (r.resultTo == null) {
  39. //此时找到的taskTop是Activity A的ActivityRecord,
  40. //因为Actvity B和A的ActivityRecord所在的Task是相关的
  41. ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
  42. ? findTaskLocked(intent, r.info)
  43. : findActivityLocked(intent, r.info);
  44. //找到了相关task
  45. if (taskTop != null) {
  46. //重设task的intent
  47. if (taskTop.task.intent == null) {
  48. //...
  49. }
  50. //此时找到的task已在栈顶
  51. ActivityRecord curTop = topRunningNonDelayedActivityLocked(notTop);
  52. if (curTop != null && curTop.task != taskTop.task) {
  53. //... 这里的代码不会执行
  54. }
  55. //launchFlags为0
  56. if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
  57. taskTop = resetTaskIfNeededLocked(taskTop, r);
  58. }
  59. //... 一般情况下startFlags 不会设置 START_FLAG_ONLY_IF_NEEDED
  60. if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
  61. //...
  62. }
  63. // ==================== begin
  64. // launchFlags此时为0
  65. if ((launchFlags &
  66. (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
  67. == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
  68. //...这里的代码不执行
  69. } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
  70. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
  71. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
  72. // r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
  73. // 故此会进入该分支
  74. //因为B还从未启动,故此得到的top为null
  75. ActivityRecord top = performClearTaskLocked(
  76. taskTop.task.taskId, r, launchFlags);
  77. if (top != null) {
  78. //...这里的代码不执行
  79. } else {
  80. addingToTask = true;
  81. sourceRecord = taskTop;
  82. }
  83. } else if (r.realActivity.equals(taskTop.task.realActivity)) {
  84. //...这里的代码不执行
  85. } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
  86. //...这里的代码不执行
  87. } else if (!taskTop.task.rootWasReset) {
  88. //...这里的代码不执行
  89. }
  90. // ==================== end
  91. // 此时 addingToTask为true
  92. if (!addingToTask && reuseTask == null) {
  93. //...这里的代码不执行
  94. }
  95. }
  96. }
  97. }
  98. //...
  99. if (r.packageName != null) {
  100. ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
  101. if (top != null && r.resultTo == null) {
  102. //此时task还没有B的ActivityRecord,故此不会进入下述分支
  103. if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
  104. //...这里的代码不执行
  105. }
  106. }
  107. } else {
  108. //...这里的代码不执行
  109. }
  110. boolean newTask = false;
  111. boolean keepCurTransition = false;
  112. // 此时 r.resultTo == null addingToTask为true sourceRecord != null
  113. if (r.resultTo == null && !addingToTask
  114. && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
  115. //...这里的代码不执行
  116. } else if (sourceRecord != null) {
  117. if (!addingToTask &&
  118. (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
  119. //...这里的代码不执行
  120. } else if (!addingToTask &&
  121. (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
  122. //...这里的代码不执行
  123. }
  124. //将B的ActivityRecord加入A的ActivityRecord所在的Task里
  125. r.setTask(sourceRecord.task, sourceRecord.thumbHolder, false);
  126. //...
  127. } else {
  128. //...这里的代码不执行
  129. }
  130. //...
  131. startActivityLocked(r, newTask, doResume, keepCurTransition, options);
  132. return ActivityManager.START_SUCCESS;
  133. }

总结

从上面的分析可以看出来,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

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

android Activity启动过程(四)startActivityUncheckedLocked的更多相关文章

  1. android Activity启动过程(一)从startActivty开始说起

    从启动startActivity开始说起 MainActivity.startActivity() Activity.startActivity() Activity.startActivityFor ...

  2. [Android]Activity启动过程

    Android系统启动加载流程: 参考图 Linux内核加载完毕 启动init进程 init进程fork出zygote进程 zygote进程在ZygoteInit.main()中进行初始化的时候for ...

  3. android Activity启动过程(三)从栈顶Activity的onPause到启动activityon的Resume过程

    ActivityStack.startPausingLocked() IApplicationThread.schudulePauseActivity() ActivityThread.sendMes ...

  4. android Activity启动过程(二)从ActivityManagerService的startActivity到栈顶Activity的onPause过程

    ActivityManagerService.startActivity() ActvityiManagerService.startActivityAsUser() ActivityStackSup ...

  5. Android深入四大组件(四)Android8.0 根Activity启动过程(前篇)

    前言 在几个月前我写了Android深入四大组件(一)应用程序启动过程(前篇)和Android深入四大组件(一)应用程序启动过程(后篇)这两篇文章,它们都是基于Android 7.0,当我开始阅读An ...

  6. Android深入四大组件(五)Android8.0 根Activity启动过程(后篇)

    前言 在几个月前我写了Android深入四大组件(一)应用程序启动过程(前篇)和Android深入四大组件(一)应用程序启动过程(后篇)这两篇文章,它们都是基于Android 7.0,当我开始阅读An ...

  7. Android 面试必备 - 系统、App、Activity 启动过程“一锅端”

    Android 系统启动过程 从系统层看: linux 系统层 Android系统服务层 Zygote 从开机启动到Home Launcher: 启动bootloader (小程序:初始化硬件) 加载 ...

  8. Android应用程序的Activity启动过程简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6685853 在Android系统中,Activ ...

  9. Android世界第一个activity启动过程

    Android世界第一个activity启动过程 第一次使用Markdown,感觉不错. Android系统从按下开机键一直到launcher的出现,是一个如何的过程,中间都做出了什么操作呢.带着这些 ...

随机推荐

  1. Socket编程--TCP服务端注意事项

    僵尸进程处理 僵尸进程和孤儿进程: 基本概念:我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程.子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预 ...

  2. DropDownList 控件的SelectedIndexChanged事件触发不了

    先看看网友的问题: 根据Asp.NET的机制,在html markup有写DropDownList控件与动态加载的控件有点不一样.如果把DropDownList控件写在html markup,即.as ...

  3. “网易大数据讲堂第一期:数说”直播活动资料:课程回放收看及PPT下载

    欢迎访问网易云社区,了解更多网易技术产品运营经验. "网易大数据讲堂第一期:数说"直播活动昨晚顺利举行.感谢各位"数"友的支持和参与. 本次活动PPT可点击这里 ...

  4. gRPC官方文档(概览)

    文章来自gRPC 官方文档中文版 概览 开始 欢迎进入 gRPC 的开发文档,gRPC 一开始由 google 开发,是一款语言中立.平台中立.开源的远程过程调用(RPC)系统. 本文档通过快速概述和 ...

  5. ubuntu - 安装sqoop

    解析过程 参考:https://www.cnblogs.com/qingyunzong/p/8807252.html#_label4 一.下载 二.解压到指定目录 三.配置sqoop环境变量并生效 四 ...

  6. AI进阶之路

    一.方法论 二.发展趋势 三.入门查看 1. https://hongyuxie.github.io/MyResume_CN/ 上班后大家还刷算法题吗 编程面试的 10 大算法概念汇总 技术面试宝典: ...

  7. Python从小看到大

    最近迷恋上了python,因为一个朋友说python这种脚本语言很厉害,可以做网络攻防的时候用,但是由于自己太笨了,不得不从基础教程学起. 行左右.你可能会问为什么这么少的代码量,这门语言没有火起来, ...

  8. ajax遍历数据生成下拉框

    <script type="text/javascript">        function GetEQIDList(ModuleID)    {        $. ...

  9. rest framework认证组件和django自带csrf组件区别详解

    使用 Django 中的 csrf 处理 Django中有一个django.middleware.csrf.CsrfViewMiddleware中间件提供了全局的csrf检查.它的原理是在<fo ...

  10. 剑指offer —— 从尾到头打印链表

    1.问题:输入一个链表,从尾到头打印链表每个节点的值. /** * public class ListNode { * int val; * ListNode next = null; * * Lis ...