什么是onCreate(Bundle savedInstanceState)函数?

131
有人能帮我了解在onCreate(Bundle savedInstanceState)中的Bundle savedInstanceState吗?我是Android的新手。我尝试从developer.android.com上理解它,但我无法理解。有人可以简化一下吗?

2
这是一个好视频:https://www.youtube.com/watch?v=kkYIMZw9gzQ - Francisco Corrales Morales
作为第一手参考,我在这里留下了这个链接:https://developer.android.com/guide/components/activities/activity-lifecycle#oncreate - carloswm85
5个回答

110
如果您在捆绑包中保存应用程序的状态(通常是非持久性的动态数据在onSaveInstanceState中),则可以将其传递回onCreate,如果活动需要重新创建(例如,方向更改),以便您不会丢失此先前信息。如果没有提供数据,则savedInstanceState为null。
您应该使用onPause()方法将任何持久性数据(例如用户编辑)写入存储。另外,onSaveInstanceState(Bundle)方法在将活动放置在这样的后台状态之前调用,允许您将活动中的任何动态实例状态保存到给定的Bundle中,以便稍后在onCreate(Bundle)中接收,如果活动需要重新创建。有关进程生命周期如何与其托管的活动相关联的更多信息,请参见进程生命周期部分。请注意,重要的是将持久数据保存在onPause()中,而不是onSaveInstanceState(Bundle)中,因为后者不是生命周期回调的一部分,因此不会在其文档中描述的每种情况下被调用。 source

2
其他活动是否共享同一 Bundle?如果我启动另一个活动,它是否会从第一个活动传递 Bundle? - Francisco Corrales Morales

18

onCreate(Bundle savedInstanceState)方法用于在Activity第一次启动时获取Bundle对象,并且当屏幕方向发生改变时再次使用该对象......

Android提供另一种优雅的方式来实现此目的。为了实现该目标,我们需要重写一个名为onSaveInstanceState()方法。 Android平台允许用户保存任何状态,状态可以保存在Bundle中,Bundle作为参数传递给onSaveInstanceState方法。

我们可以在onCreate方法中通过传递给它的Bundle对象加载保存的实例状态。我们还可以在onRestoreInstanceState方法中加载已保存的实例状态。但是我会留给读者自行解决。

http://www.gitshah.com/2011/03/how-to-handle-screen-orientation_28.html


11
如果之前调用了onSavedInstanceState(),那么savedInstanceState将不为空。屏幕方向更改只是可能发生这种情况的一个示例。 - Alex Lockwood
1
@AlexLockwood,我正在尝试考虑可能发生这种情况的所有情形。有没有相关文档?我能想到的一个例子是,如果用户切换应用程序并返回,但活动已被销毁以恢复资源。在这种情况下,如果覆盖了onSaveInstanceState()方法,Android会重新创建带有Bundle的活动,对吗? - batbrat
1
@batbrat 是的...我之前发表的评论(将近两年前)并不完全正确。我想最好的说法是,只有在Activity之前调用了它的onSaveInstanceState方法时,onCreate(Bundle)Bundle参数才会非空。这在方向更改期间发生...当活动在被操作系统杀死后重新启动,并且当您在设备上触发任何其他感兴趣的配置更改时也会发生。 - Alex Lockwood
谢谢澄清,Alex。对于这个主题有一些明确的了解是很好的。我特别是忘记了除方向切换之外的配置更改。 - batbrat

17

如Dhruv Gairola所回答的那样,您可以使用Bundle savedInstanceState来保存应用程序的状态。我正在尝试提供一个非常简单的示例,以便像我这样的新学习者可以轻松理解。

假设您有一个简单的片段,其中包含一个TextView和一个Button。每次点击按钮时,文本会更改。现在,更改设备/模拟器的方向,并注意到您丢失了数据(即点击后获得的更改数据),片段又重新开始了。通过使用Bundle savedInstanceState,我们可以摆脱这个问题。如果您查看片段的生命周期Fragment Lifecylce,您将得到一个方法“onSaveInstanceState”,当片段即将销毁时调用该方法。

因此,我们可以将更改的文本值保存到该bundle中,如下所示:

 int counter  = 0;
 @Override
 public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("value",counter);
 }

你进行方向调整后,“onCreate”方法就会被调用,对吧?那么我们就可以这样做。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if(savedInstanceState == null){
        //it is the first time the fragment is being called
        counter = 0;
    }else{
        //not the first time so we will check SavedInstanceState bundle
        counter = savedInstanceState.getInt("value",0); //here zero is the default value
    }
}

现在,您不会在定向后失去价值。修改后的价值始终会显示。


请注意,这也适用于Activity。您能否更详细地解释一下(Activity的Bundle)和(Fragment的Bundle)之间的区别? - laalaguer
您可以从活动和片段的生命周期中清楚地了解一个活动可以同时显示多个片段。因此,基本区别在于,如果您想为活动的所有片段保存一些值,则应使用活动的bundle;否则,如果是针对特定片段,应使用片段的bundle。 - Asad

4

onCreate(Bundle) 方法在 Activity 第一次启动时被调用。你可以用它来进行一次性的初始化,比如创建用户界面。 onCreate() 接受一个参数,该参数为 null 或者是由 onSaveInstanceState 之前保存的某些状态信息。


0

当调用onCreate(Bundle savedInstanceState)方法时,如果您的Activity在上述场景(视觉视图)中被终止,则savedInstanceState将不为空。然后,您的应用程序可以从savedInstanceState中获取数据并重新生成Activity。


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