安卓Activity实例状态

10

什么是以下内容的意义:

super.onCreate(null);

替代

super.onCreate(savedInstanceState);

通过这种改变,我可以避免许多问题,否则每次发生配置更改(旋转、区域设置转换、权限切换)时都会困扰我的Activity。似乎通过这种改变,每当配置更改触发它重新启动时,Activity就会重新开始。我似乎没有因此丢失任何数据或处理状态:所有我的Activity都恢复到了它们原来的状态。
我的问题是,我能否从此毫不顾忌地这样做,还是在交易中失去了一些东西?我真的不明白为什么这样可以工作,它是否安全,以及它可能对我的应用程序产生的意外影响。
我在这里偶然发现了这个技巧 相关问题: 使用null参数调用super.onCreate()? Application被杀死后,'Bundle savedInstanceState'会存活吗? Activity状态实例 - 洞察力? Activity的实例状态:自动存储和恢复了什么

1
所有我的活动都恢复到它们以前的状态,这真的很奇怪。如果您执行super.onCreate(null),您应该失去所有先前的状态。您确定在AndroidManifest.xml中没有指定configChanges标志吗? - azizbekian
你是否正在使用碎片?你所面临的问题是否与链接技巧有关?(https://coderanch.com/t/602443/Dynamic-Fragments-access-recreated-saved) - user3956566
1
@Y.S. 你能详细说明一下 ...我能够避免在每次配置更改时影响我的Activity的许多问题 吗?调用super.onCreate() ... 回答了你的问题。你基本上是在打破契约,即使你现在可以忍受副作用,但你不能确定这样做是否会以任何方式破坏它。我几乎可以肯定,你不会看到崩溃(null 是一个可接受的值)。我想这是一个权衡的情况,除非你已经误识了你的 问题 的根本原因。 - Vikram
1
@Y.S. 我不建议这样做。但是,如果你必须这样做,请仔细查看源代码以确定可能的副作用。AppCompatDelegateImpl Activity 如果您能够将问题通过传递状态原封不动地编辑到您的问题中,我会非常感激。 - Vikram
@Vikram:这与在运行时权限切换(来自设置)后重新启动Activity后出现的某些不必要的影响有关。我需要Activity重新启动为全新的实例。 - Yash Sampat
显示剩余4条评论
5个回答

2
onCreate()是在活动即将创建时首先调用的。此外,Android系统管理活动生命周期,并且可以在用户长时间不关注活动且系统内存不足的情况下保存其instanceState并终止活动。
一个活动基本上有四种状态。
super.onCreate(null):始终会创建活动,即使Android系统提供了它的savedInstanceState,也无论方向配置如何。
super.onCreate(savedInstanceState):活动可以使用“savedInstanceState”来重置其状态或组件的位置。
为了实现这一点,活动的实例状态需要在失去用户注意力(可能是onStop或onDestroy)之前持久化。
savedInstanceState还可以处理活动配置发生更改时的重要性,请查看Configuration change中的活动生命周期行为。

1

我会失去什么吗?

只有当你在使用Fragment时才会失去一些东西。请参见Calling super.onCreate() with null parameter?

是的,onCreate(...)是启动Activity所必需的,但当你在使用Fragment时,传递Bundle作为参数是必须的。

Read this

你从中推断出了什么?

无论如何,参数savedInstanceState默认情况下总是null。因此,在交易中你实际上不会失去任何东西。

但是等等,我们通常使用Bundles来维护方向的改变,对吧?

以下清单代码声明了一个处理屏幕方向改变和键盘可用性改变的活动:

<activity android:name=".MyActivity"
          android:configChanges="orientation|keyboardHidden"
          android:label="@string/app_name">

现在,当这些配置之一发生变化时,MyActivity不会重新启动。相反,MyActivity会接收到一个调用 onConfigurationChanged() 的方法。该方法传递了一个 Configuration 对象,指定了新的设备配置。通过读取 Configuration 中的字段,您可以确定新的配置,并通过更新界面中使用的资源来进行适当的更改。在调用此方法时,您的活动的 Resources 对象会更新为基于新配置返回资源,因此您可以轻松地重置 UI 元素,而无需系统重新启动您的活动。

以下的onConfigurationChanged()实现检查当前设备方向:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}

但是请记住:当您声明您的活动来处理配置更改时,您需要负责重置任何为其提供替代方案的元素。如果您声明您的活动来处理方向更改并且有应在横向和纵向之间更改的图像,则必须在onConfigurationChanged()期间为每个元素重新分配每个资源。

0
据我所知,许多数据保存在bundle的savedInstanceState中。例如,您当前布局中所有视图的状态,如任何EditTextCheckBox的当前内容。
您还可以查找一些官方来源,以检查是否需要保留某些数据。 这里有一篇不错的文章 基本上,它说所有View类都实现了onRestoreInstanceStateonSaveInstanceState方法,这些方法保存和恢复了它们在状态更改之前的任何临时状态。

-1

当您更改设备的旋转时,存储在类变量或局部变量中的所有数据都会丢失。但是在您的活动中,只要用户输入任何数据,就看起来像您没有存储任何数据,而是在单击按钮或类似操作时读取数据,您的活动将正常工作,所有用户输入,例如EditText中的文本,将由Android自身恢复,因为它识别到每个视图分配的“ID”(android:id="@+id/anyID"),并可以自行恢复用户插入的所有值。

希望这能帮助到您...

愉快编码 :)


-1

savedInstanceState 是一个 Bundle 对象的引用,它被传递到每个 Android Activity 的 onCreate 方法中。在特殊情况下,Activity 可以使用存储在此 Bundle 中的数据将自己恢复到先前的状态。

使用 savedInstantState 从 Intent 中获取值并保存在 bundle 中非常重要。


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