对 activity 生命周期感到困惑

Confused about activity lifecycle

我对 activity 生命周期的某些方面有点困惑。

假设您有两个 Activity A 和 B,A 是启动 activity。您启动应用程序,然后 A 通过 onCreate()、onStart() 等。在 onCreate() 之前 activity class 对象被实例化,因此您可以在 onCreate() 中创建您需要的任何附属项。

然后您使用 startActivity() 来启动 activity B。A 经历 onPause() 等,B 像 A 一样经历启动过程。

现在说你想回到 A。有两种方法 - finish()(或 onBackPressed() / 后退按钮似乎做同样的事情),或使用 startActivity() 启动 A。A 应该是在历史堆栈上,除非使用 'noHistory'.

创建

使用 finish() 或返回,A 现在运行通过 onRestart()、onStart() 等 - 而不是 onCreate() - 这似乎是有道理的。也就是说,除非它同时由于内存限制而被杀死,否则它会从原来的位置继续运行。但是,对于 startActivity(),它总是通过 onCreate()、onStart() 等代替。这意味着第一次在 onCreate() 中设置的所有内容都会再次完成。假设它在历史堆栈上,为什么它不走 onRestart() 路线?

是不是每当通过 startActivity() 启动 activity 时,(1) class 对象实际上总是重新实例化,因此必须在onCreate() 或 (2) 是先前使用的实例化(如果存在),因此可以在 onCreate() 中检测到它并有效地将通过 onCreate() 的传递视为 onRestart() 吗?

Assuming it is on the history stack, why doesn't it go the onResume() route?

因为调用 startActivity,默认情况下会创建 Activity 的新实例。每个实例都贯穿整个生命周期。因此,在您的示例中,它并不是真正的 A -> B -> A。它更像是 A1 -> B -> A2,其中 A1 和 A2 是 activity 的 实例 答.

启动 A 的第二个实例时,就像从 A 的第一个实例创建 B 一样。它是一个全新的对象,因此必须从头开始创建。

Is it the case that whenever an activity is started via startActivity(), (1) the class object is actually always instantiated afresh and every else hanging off it must therefore be recreated in onCreate() or, (2) is the previous instantiation used, and can one therefore detect that in onCreate() and effectively treat that pass through onCreate() as an onResume()?

如前所述,通常 (1)。这就是 default 行为。但是,您可以通过使用适当的 launch mode flags. In which case the existing instance will be brought to the front of the stack, go through onStart and onResume (skipping onCreate since it already existed), but then also getting a call to onNewIntent 接收 - 嗯 - 再次启动它的新意图,使应用程序导航到 A 的现有实例。

在这种情况下,它是 A -> B -> A,因为您正在导航到 A 的已经存在的原始实例,而不是创建一个新实例。


编辑

Having looked further, does one get a similar result if A starts B with startActivityForResult()? Ie would the result come back to the original instance of A?

“相似”但不相同。主要区别在于您的导航堆栈发生了什么。

如果你执行 A -> startForResult -> B,然后完成 B 并且 return 你的结果,你剩下 A。

如果你执行 A -> B -> startSingleTop -> A 那么你最终会在堆栈中得到 B 和 A。所以如果你从 A 退缩,你最终会回到 B。

此外,请记住,使用 Android,您几乎永远无法保证返回到任何 activity 的“原始实例”。当 A 在后台而你在 B 上时,如果系统需要内存,它可以杀死 A 的那个实例。无论您是使用单个任务启动 A 还是在 startForResult 之后对它启动 return,您都可能会返回到一个新的 实例 .

The reason I am looking at this is to make B like a dialog box for A. Ie, run A, go to B and adjust something, back to A and continue where left off

对于那种情况,startActivityForResult 将是最好的做法。一般来说,除非真的有必要并且你真的知道你在做什么,否则避免使用启动模式标志 - 它很快就会变得复杂。