当应用程序被杀死后,'Bundle savedInstanceState'是否仍然存在?

16

onCreate()方法中的savedInstanceState捆绑包在应用程序被杀死后是否仍然存在(非null)?如果是的话,这个捆绑包存储在系统中的哪里。

5个回答

24
如果Android杀死了托管您的应用程序的进程,它仍会保留所有活动(非完成状态)的“保存实例状态”。这些数据由ActivityManager存储。如果用户返回您的应用程序,Android将为该应用程序创建一个新进程,再次实例化Application实例,然后创建一个活动堆栈中的顶部活动实例。然后,它将调用那个活动实例上的onCreate(),并传递最近为该活动保存的“保存实例状态”。
如果您重新启动手机,则所有此类数据都会丢失(Android不会跨重新启动保存应用程序状态)。

9
自 API 21 起,当 savedInstanceState 设置为 persistableMode 时,它可以在重新启动后仍然存在。该 Bundle 将会作为第二个参数传递到 onCreate(Bundle, PersistableBundle) 方法中。 - passsy
1
正如@passsy所指出的那样,有一个重载的新方法onSaveInstanceState',它带有PersistableBundle作为额外参数。如果你想知道为什么你的onSaveInstanceState`没有被调用,可能是因为你正在使用这个新方法。 - Burak Dede
也许还有一个后续问题。在重新启动设备之前存在的任务是否也会保留下来?我认为是的,但我没有在任何地方看到它有记录。 - stdout
1
@stdout 不,任务不会在重启后保留。当您启动设备时,您会注意到最近任务列表为空。 - David Wasser

7
不会,只要应用程序在前台或后台运行,安卓应用程序将保持其状态。
如果你想要跨越应用程序的不同生命周期,可以使用像SharedPreferences这样的东西。
关于“如果系统杀死你的应用程序进程并且用户浏览回到你的活动”:
仅当Android需要内存并且必须杀死您的活动以释放资源和您的活动在活动堆栈中时才会发生。它已经记录了这是一种方便的方式来维护用户体验。
Android文档:
一个后台活动(一个对用户不可见并已暂停的活动)不再是关键的,所以系统可以安全地杀死其进程以为其他前台或可见进程腾出内存。如果它的进程需要被杀死,当用户导航回该活动时(再次在屏幕上可见),其onCreate(android.os.Bundle)方法将使用先前在onSaveInstanceState(android.os.Bundle)中提供的savedInstanceState进行调用,以使自己以与用户上次离开时相同的状态重新启动。

因此,您不应期望InstanceState始终保持。

Activity源代码在codegrep上

编辑

通过搜索google的android instance state,我找到了这个资源Android重新创建Activity

当用户按下Back键或Activity自行完成时,系统会销毁您的Activity。这意味着该Activity实例的系统概念将永远消失,因为行为表明不再需要该Activity。但是,如果系统由于系统限制(而不是正常应用程序行为)而销毁Activity,则尽管实际Activity实例已经消失,系统仍会记住它的存在,以便如果用户导航回到该Activity,则使用一组保存的数据创建Activity的新实例,描述了Activity被销毁时的状态。系统用于恢复先前状态的保存数据称为“instance state”,是存储在Bundle对象中的一组键值对集合。

编辑2 在深入研究Android内部后,似乎一切都与ActivityManagerNative有关。

每当一个活动暂停时,它的状态都会使用Parcel对象传递到ActivityManager进程中。

    public void activityPaused(IBinder token, Bundle state) throws RemoteException
{
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    data.writeStrongBinder(token);
    data.writeBundle(state);
    mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
    reply.readException();
    data.recycle();
    reply.recycle();
}

每当 ActivityManagerNative 创建一个活动时,它会使用 Parcel 将该状态传递回活动。
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
    case START_ACTIVITY_TRANSACTION:
    {
        data.enforceInterface(IActivityManager.descriptor);
        IBinder b = data.readStrongBinder();
        IApplicationThread app = ApplicationThreadNative.asInterface(b);
        Intent intent = Intent.CREATOR.createFromParcel(data);
        String resolvedType = data.readString();
        Uri[] grantedUriPermissions = data.createTypedArray(Uri.CREATOR);
        int grantedMode = data.readInt();
        IBinder resultTo = data.readStrongBinder();
        String resultWho = data.readString();    
        int requestCode = data.readInt();
        boolean onlyIfNeeded = data.readInt() != 0;
        boolean debug = data.readInt() != 0;
        int result = startActivity(app, intent, resolvedType,
                grantedUriPermissions, grantedMode, resultTo, resultWho,
                requestCode, onlyIfNeeded, debug);
        reply.writeNoException();
        reply.writeInt(result);
        return true;
    }
   .....

1
文档中说:“如果系统终止了您的应用程序进程并且用户返回到您的活动,则系统会重新创建该活动并将Bundle传递给onCreate()和onRestoreInstanceState()。” 我有什么遗漏吗? - Eugene
如果应用程序被杀死,实例状态为什么会保存也有一个很好的解释。https://www.youtube.com/watch?v=fL6gSd4ugSI&feature=youtube_gdata_player - Eugene
当用户按下返回键或活动自行完成时,您的活动被销毁时,系统对该活动实例的概念将永远消失,因为该行为表明该活动不再需要。我一直在寻找这个,谢谢! - Lance Toth

4

以下的表格来自于 Android 培训材料,或许更有帮助。

在这个表格中,通过 onSavedInstanceState 保存的 Bundle 对象仅在应用程序处于打开状态时才有效。这意味着应用程序可以被暂停、甚至停止和销毁(由于旋转等原因),但不能使用返回按钮退出。

该表格还展示了其他可用选项,如果不使用 onSavedInstanceState

enter image description here


2
这里的答案有点过时了。在2021年,savedInstanceState会被写入磁盘并在再次创建活动时在onCreate中可用,因此会跨设备重启保留。
官方文档指出,onSavedInstanceState()将数据序列化到磁盘上,所以保存的实例状态包会通过配置更改和进程死亡而持久化。 文档链接

不行了。我试着重新启动手机,但我的应用程序仍然从主屏幕打开。 - undefined

0
Android文档确实说明savedInstanceState会在进程死亡后保留,但是在我的测试中并没有这样。你可以通过点击顶部工具栏上的红色按钮来模拟进程死亡1
可能情况是当Android系统终止进程时,onSaveInstanceState捆绑包可能不会被销毁,但是当我们手动终止进程时,它可能会被销毁。
以下是Android文档提供的概述。

enter image description here

你可以阅读更多这里


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