onStart()和onResume()的区别

191

我不理解 onStart() 过渡状态的意义。无论如何,onResume() 方法总是在 onStart() 之后被调用。为什么不能让 onResume() 在除了 onStart() 以外的方法(比如 onRestart()onCreate())之后被调用呢?它的目的是什么?

为什么我们离不开 onStart()。我仍然认为它是多余的(可能是因为我没有完全理解它的含义)。


请查看以下应用程序生命周期:http://d.android.com/guide/topics/fundamentals.html - ykatchou
这东西很容易。现在试着用Fragment解释一下,那才是真正的安卓编程! - SMBiggs
这是一段代码,用片段解释了它。 - Atul
12个回答

321

为什么onResume()方法不能在onRestart()和onCreate()方法之后调用,只排除onStart()方法?它的目的是什么?

好的,既然我的第一个答案已经很长了,我不会再进一步延伸,那么让我们尝试这个简短的回答...

public DriveToWorkActivity extends Activity
    implements onReachedGroceryStoreListener {
}

public GroceryStoreActivity extends Activity {}
请注意:我故意省略了像super.onCreate(...)等调用。这是伪代码,所以请给我一些艺术许可。;) DriveToWorkActivity的方法如下...
protected void onCreate(...) {
    openGarageDoor();
    unlockCarAndGetIn();
    closeCarDoorAndPutOnSeatBelt();
    putKeyInIgnition();
}

protected void onStart() {
    startEngine();
    changeRadioStation();
    switchOnLightsIfNeeded();
    switchOnWipersIfNeeded();
}

protected void onResume() {
    applyFootbrake();
    releaseHandbrake();
    putCarInGear();
    drive();
}

protected void onPause() {
    putCarInNeutral();
    applyHandbrake();
}

protected void onStop() {
    switchEveryThingOff();
    turnOffEngine();
    removeSeatBeltAndGetOutOfCar();
    lockCar();
}

protected void onDestroy() {
    enterOfficeBuilding();
}

protected void onReachedGroceryStore(...) {
    Intent i = new Intent(ACTION_GET_GROCERIES, ...,  this, GroceryStoreActivity.class);
}

protected void onRestart() {
    unlockCarAndGetIn();
    closeDoorAndPutOnSeatBelt();
    putKeyInIgnition();
}

好的,这是一个有点长的问题(对不起),但是这是我解释的方法...

onResume() 是当我开始驾驶时调用的函数,而 onPause() 是当我暂停时调用的。所以我驾驶,然后到达红灯,所以我暂停...当灯变绿色时我继续行驶。另一个红灯,我再次暂停,然后灯变绿色我就继续行驶了。onPause() -> onResume() -> onPause() -> onResume() 这个循环是一个紧密的循环,并且在我的旅途中经常出现。

从停止状态到重新开始(准备继续我的旅程)的循环可能不太常见。在某些情况下,我会看到杂货店,然后启动 GroceryStoreActivity(强制使我的 DriveToWorkActivity 调用 onStop())。当我从商店回来时,我通过 onRestart()onStart() 再次开始我的旅程。

我可以将在 onStart() 中的代码放到 onCreate()onRestart() 中,而不必重写 onStart(),但是在 onCreate() -> onResume()onRestart() -> onResume() 之间需要做更多的事情,这将导致重复。

所以,再次引用一下...

为什么不是在 onRestart() 和 onCreate() 方法之后调用 onResume(),而只是排除 onStart() 呢?

如果您不重写 onStart(),那么这实际上就是发生的事情。虽然 ActivityonStart() 方法会被隐式调用,但在您的代码中的效果实际上是 onCreate() -> onResume() 或者 onRestart() -> onResume()


1
这意味着onCreate()onRestart()两者会共享很多相同的代码,对吗? - Dheeraj Vepakomma
1
@Dheeraj:不一定。这是伪代码,旨在说明每个“Activity”生命周期阶段可能如何使用。创建阶段的 onCreate(...) 在实例化实例成员(UI元素等)方面可能会做很多工作,但“重新启动”不需要这样做。实际上,许多“Activities”不需要实现更多的方法,只需要实现onCreate(...)onResume()onPause()即可,其他方法可用于可能需要执行其他操作的情况,关键是要理解在哪里放置代码。 - Squonk
1
这就是为什么我开始厌恶Android API,相比iOS和WP7...我一直在用C#制作一个可以在这三个平台上运行的游戏,我必须说我对Google和Android感到非常失望。它们似乎在语言/API设计方面缺乏了一些东西。我真的希望其他Linux手机操作系统能够接管,因为我总体上支持开源... - zezba9000
2
@Tim:好的,提出一个更好的设计。如果有人在使用你的应用程序时突然接到电话,你会如何处理移动电话上的场景?应用程序设计师不会显式调用“Activity”生命周期方法 - 它是由Android操作系统自动完成的,并且它非常高效(假设应用程序开发人员知道他们在做什么并且编写有效的代码)。如果您进行大量的Android开发,您将意识到为什么事情会按照它们的方式工作 - 这不是100%完美的,但它相当不错。 - Squonk
14
我认为下面Nilesh的回答更加清晰。onStartonResume之间的关键差异在于“可见性”和“用户交互”。这个开车的比喻很令人困惑,也不是很有帮助。 - K J
显示剩余3条评论

167

简短回答:

我们不能没有onStart,因为这是活动变得“可见”但用户还无法“交互”的状态,可能是因为它与某些其他小对话框重叠了。这种与用户交互的能力是区分onStart和onResume的关键。将其视为玻璃门后面的人。你可以看到这个人,但你不能与他互动(交谈/听/握手)。onResume就像门的开启器,之后你就可以开始互动了。

此外,onRestart()是最不被理解的一个。我们可以问为什么不直接在onStop()之后转到onStart()或onResume()而是要用onRestart()呢?如果省略创建部分,则onRestart()在某种程度上等同于onCreate()。基本上,两种状态都会导致onStart()(即Activity变得可见)。因此,这两种状态都必须“准备”要显示的内容。onCreate还有额外的责任来“创建”要显示的内容。

因此,它们的代码结构可能类似于:

onCreate()
{
     createNecessaryObjects();

     prepareObjectsForDisplay();
}


onRestart()
{
     prepareObjectsForDisplay();

}
整个混淆是由于谷歌选择了不直观的名称,而不是以下类似内容所引起的:
onCreateAndPrepareToDisplay()   [instead of onCreate() ]
onPrepareToDisplay()            [instead of onRestart() ]
onVisible()                     [instead of onStart() ]
onBeginInteraction()            [instead of onResume() ]
onPauseInteraction()            [instead of onPause() ]
onInvisible()                   [instead of onStop]
onDestroy()                     [no change] 
活动图可以解释为:

Android Activity Lifecycle


5
当我向学生解释时,我使用maybeOnInvisible()代替onStop()。并且使用maybeOnDestroy()代替onDestroy()。我发现这些名称作为解释很有效。但我不希望Google实际上更改为这些名称。 - Stephan Branczyk
如果您的Activity被其他东西覆盖但不完全(它仍然在那个东西下可见但不在前台),那么将触发onPause -> OnResume。我会说http://developer.android.com/reference/android/app/Dialog.html是一个很好的例子,但我没有检查过。 - Marian Paździoch
1
@StephanBranczyk,您能解释一下发生了什么变化吗?我测试了一下,当对话框或菜单在活动前面打开时(因此活动部分被覆盖),既不会触发onPause()也不会触发onResume()。实际上,我无法重现任何只有onResume()而没有onStart()的情况。这让我感到困惑... - Damnum
1
@Damnum,关于Activity生命周期的最新解释,我建议你查看由Google创建的中级Android Udacity课程。它是免费的,只要你点击蓝色按钮以免费访问其材料,而不是试用按钮(也不是纳米学位按钮)。https://www.udacity.com/course/developing-android-apps--ud853 - Stephan Branczyk
1
@Damnum,我建议你在与你观看的视频相关的Udacity论坛上提出这个问题。但基本上,我认为这取决于所使用的对话框,无论是对话框活动还是仅对话框。 - Stephan Branczyk
显示剩余5条评论

31

onStart()会在Activity对用户可见时调用。 onResume()会在Activity即将开始与用户交互时调用。 你可能需要在这些情况下执行不同的操作。

请参阅此链接以获取更多信息。


20

10

这本书名为“Hello, Android, Introducing Google's Mobile Development Platform”,详细阐述了Android应用程序的生命周期,幸运的是,他们将特定章节作为网络摘录。请参见第39页上的图形, http://media.pragprog.com/titles/eband3/concepts.pdf

顺便说一句,这本书非常适合初学者阅读!


2
好的图片和好的书,但它仍然没有回答为什么我们真正需要onStart()方法以及我们可以在其中做哪些特殊的事情,而不能在onResume()中做。 - Eugene
8
如果应用程序被暂停,onStart()方法将不会被调用。如果另一个应用程序获得焦点但未完全遮挡您的应用程序,则您的应用程序处于“暂停”状态。因此,在“暂停”状态下,您可以执行与“停止”状态下不同的操作。因此,如果您的应用程序从暂停状态“恢复”,则可以执行不同的操作,而如果您的应用程序从完全启动或停止状态“启动”,则可以执行其他操作。这样有帮助吗? - Martin Booka Weser

9

onStart()

  1. 在 onCreate(Bundle) 或 onRestart() 之后调用,接着是 onResume()
  2. 可以在 onStart() 中注册 BroadcastReceiver 监听影响 UI 的变化,但必须在 onStop() 中注销它。
  3. 派生类必须调用超类的此方法实现。如果不这样做,将抛出异常。

onResume()

  1. 在 onRestoreInstanceState(Bundle)、onRestart() 或 onPause() 之后调用。
  2. 开始动画,打开独占访问设备(如相机)。

onStart() 通常将工作分派给后台线程,其返回值为:

  • START_STICKY,以自动重启并保持活动状态。

  • START_REDELIVER_INTENT,以在 stopSelf() 之前如果服务被杀死时进行自动重启和重试。

当设备进入休眠状态或 Alert 或其他部分屏幕子活动离开先前窗口的一部分可见时,会调用 onResume(),因此需要一个方法来重新初始化字段(在 try 结构中,捕获异常)。这种情况不会导致 onStop() 在子项关闭时被调用。

onResume() 从后台恢复活动时被调用,而不需要 onStart()

有关更多详细信息,请访问Android_activity_lifecycle_gotchaActivity Lifecycle


当我的应用程序进入后台时,实际上我会收到onStop。 - deadfish

7
一个特别棘手的例子是,当你决定使用showDialog()从Activity中展示一个管理的Dialog时。如果用户在对话框仍然打开的情况下旋转屏幕(我们称之为“配置更改”),则主Activity将经历所有终止生命周期调用直至onDestroy(),将被重新创建,并再次通过生命周期。然而,您可能没有预料到的是,在onStart()onResume()之间调用了onCreateDialog()onPrepareDialog()(这些方法在执行showDialog()时调用,现在会自动重新创建对话框 - 自动,因为它是一个管理的对话框)。这里的重点是对话框并不覆盖整个屏幕,因此留下了主Activity的一部分可见。这是一个细节,但确实很重要!

7
希望简单解释一下:- onStart() -> 当Activity变得可见时调用,但可能不在前台(例如,AlertFragment在顶部或任何其他可能的情况)。 onResume() -> 当Activity在前台时调用,或者用户可以与Activity交互时调用。

4

onStart() 表示 Activity 进入可见状态并创建布局,但不能与此活动布局进行交互。

Resume() 表示现在可以与活动布局进行交互。


3

不确定这是否算是答案 - 但这里有一段 来自谷歌课程的YouTube视频 (使用Kotlin开发Android应用程序),解释了它们之间的区别。

  • 当活动变得可见时,On Start被调用。
  • 当活动失去焦点时(例如弹出对话框),On Pause被调用。
  • 当活动获得焦点时(例如对话框消失时),On Resume被调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接